Whamcloud - gitweb
LU-15887 test: add always_except()
[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 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env "$@"
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 always_except LU-9693  42a 42c
43 always_except LU-6493  42b
44 always_except LU-14541 277
45 always_except LU-9054  312
46 always_except LU-8411  407
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         always_except LU-14067 400a 400b
56 fi
57
58 # skip nfs tests on kernels >= 4.12.0 until they are fixed
59 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
60         always_except LU-12661 817
61 fi
62 # skip cgroup tests on RHEL8.1 kernels until they are fixed
63 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
64       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
65         always_except LU-13063 411
66 fi
67
68 #skip ACL tests on RHEL8 and SLES15 until tests changed to use other users
69 if (( $(egrep -cw "^bin|^daemon" /etc/passwd) < 2 )); then
70         always_except LU-15259 103a 125 154a
71 fi
72
73 #                                  5              12     8   12  15   (min)"
74 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
75
76 if [ "$mds1_FSTYPE" = "zfs" ]; then
77         #                                               13    (min)"
78         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
79 fi
80
81 if [ "$ost1_FSTYPE" = "zfs" ]; then
82         always_except LU-1941 130a 130b 130c 130d 130e 130f 130g
83 fi
84
85 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
86
87 # Get the SLES distro version
88 #
89 # Returns a version string that should only be used in comparing
90 # strings returned by version_code()
91 sles_version_code()
92 {
93         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
94
95         # All SuSE Linux versions have one decimal. version_code expects two
96         local sles_version=$version.0
97         version_code $sles_version
98 }
99
100 # Check if we are running on Ubuntu or SLES so we can make decisions on
101 # what tests to run
102 if [ -r /etc/SuSE-release ]; then
103         sles_version=$(sles_version_code)
104         [ $sles_version -lt $(version_code 11.4.0) ] &&
105                 always_except LU-4341 170
106
107         [ $sles_version -lt $(version_code 12.0.0) ] &&
108                 always_except LU-3703 234
109 elif [ -r /etc/os-release ]; then
110         if grep -qi ubuntu /etc/os-release; then
111                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
112                                                 -e 's/^VERSION=//p' \
113                                                 /etc/os-release |
114                                                 awk '{ print $1 }'))
115
116                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
117                         always_except LU-10334 103a
118                         always_except LU-10366 410
119                 fi
120         fi
121 fi
122
123 build_test_filter
124 FAIL_ON_ERROR=false
125
126 cleanup() {
127         echo -n "cln.."
128         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
129         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
130 }
131 setup() {
132         echo -n "mnt.."
133         load_modules
134         setupall || exit 10
135         echo "done"
136 }
137
138 check_swap_layouts_support()
139 {
140         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
141                 skip "Does not support layout lock."
142 }
143
144 check_swap_layout_no_dom()
145 {
146         local FOLDER=$1
147         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
148         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
149 }
150
151 check_and_setup_lustre
152 DIR=${DIR:-$MOUNT}
153 assert_DIR
154
155 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
156
157 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
158 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
159 rm -rf $DIR/[Rdfs][0-9]*
160
161 # $RUNAS_ID may get set incorrectly somewhere else
162 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
163         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
164
165 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
166
167 if [ "${ONLY}" = "MOUNT" ] ; then
168         echo "Lustre is up, please go on"
169         exit
170 fi
171
172 echo "preparing for tests involving mounts"
173 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
174 touch $EXT2_DEV
175 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
176 echo # add a newline after mke2fs.
177
178 umask 077
179
180 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
181 lctl set_param debug=-1 2> /dev/null || true
182 test_0a() {
183         touch $DIR/$tfile
184         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
185         rm $DIR/$tfile
186         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
187 }
188 run_test 0a "touch; rm ====================="
189
190 test_0b() {
191         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
192         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
193 }
194 run_test 0b "chmod 0755 $DIR ============================="
195
196 test_0c() {
197         $LCTL get_param mdc.*.import | grep "state: FULL" ||
198                 error "import not FULL"
199         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
200                 error "bad target"
201 }
202 run_test 0c "check import proc"
203
204 test_0d() { # LU-3397
205         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
206                 skip "proc exports not supported before 2.10.57"
207
208         local mgs_exp="mgs.MGS.exports"
209         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
210         local exp_client_nid
211         local exp_client_version
212         local exp_val
213         local imp_val
214         local temp_imp=$DIR/$tfile.import
215         local temp_exp=$DIR/$tfile.export
216
217         # save mgc import file to $temp_imp
218         $LCTL get_param mgc.*.import | tee $temp_imp
219         # Check if client uuid is found in MGS export
220         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
221                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
222                         $client_uuid ] &&
223                         break;
224         done
225         # save mgs export file to $temp_exp
226         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
227
228         # Compare the value of field "connect_flags"
229         imp_val=$(grep "connect_flags" $temp_imp)
230         exp_val=$(grep "connect_flags" $temp_exp)
231         [ "$exp_val" == "$imp_val" ] ||
232                 error "export flags '$exp_val' != import flags '$imp_val'"
233
234         # Compare client versions.  Only compare top-3 fields for compatibility
235         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
236         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
237         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
238         [ "$exp_val" == "$imp_val" ] ||
239                 error "exp version '$exp_client_version'($exp_val) != " \
240                         "'$(lustre_build_version client)'($imp_val)"
241 }
242 run_test 0d "check export proc ============================="
243
244 test_0e() { # LU-13417
245         (( $MDSCOUNT > 1 )) ||
246                 skip "We need at least 2 MDTs for this test"
247
248         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
249                 skip "Need server version at least 2.14.51"
250
251         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
252         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
253
254         [ $default_lmv_count -eq 1 ] ||
255                 error "$MOUNT default stripe count $default_lmv_count"
256
257         [ $default_lmv_index -eq -1 ] ||
258                 error "$MOUNT default stripe index $default_lmv_index"
259
260         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
261         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
262
263         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
264         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
265
266         [ $mdt_index1 -eq $mdt_index2 ] &&
267                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
268
269         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
270 }
271 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
272
273 test_1() {
274         test_mkdir $DIR/$tdir
275         test_mkdir $DIR/$tdir/d2
276         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
277         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
278         rmdir $DIR/$tdir/d2
279         rmdir $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
281 }
282 run_test 1 "mkdir; remkdir; rmdir"
283
284 test_2() {
285         test_mkdir $DIR/$tdir
286         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
287         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
288         rm -r $DIR/$tdir
289         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
290 }
291 run_test 2 "mkdir; touch; rmdir; check file"
292
293 test_3() {
294         test_mkdir $DIR/$tdir
295         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
296         touch $DIR/$tdir/$tfile
297         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
298         rm -r $DIR/$tdir
299         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
300 }
301 run_test 3 "mkdir; touch; rmdir; check dir"
302
303 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
304 test_4() {
305         test_mkdir -i 1 $DIR/$tdir
306
307         touch $DIR/$tdir/$tfile ||
308                 error "Create file under remote directory failed"
309
310         rmdir $DIR/$tdir &&
311                 error "Expect error removing in-use dir $DIR/$tdir"
312
313         test -d $DIR/$tdir || error "Remote directory disappeared"
314
315         rm -rf $DIR/$tdir || error "remove remote dir error"
316 }
317 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
318
319 test_5() {
320         test_mkdir $DIR/$tdir
321         test_mkdir $DIR/$tdir/d2
322         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
323         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
324         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
325 }
326 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
327
328 test_6a() {
329         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
330         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
331         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
332                 error "$tfile does not have perm 0666 or UID $UID"
333         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
334         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
335                 error "$tfile should be 0666 and owned by UID $UID"
336 }
337 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
338
339 test_6c() {
340         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
341
342         touch $DIR/$tfile
343         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
344         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
345                 error "$tfile should be owned by UID $RUNAS_ID"
346         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
347         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
348                 error "$tfile should be owned by UID $RUNAS_ID"
349 }
350 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
351
352 test_6e() {
353         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
354
355         touch $DIR/$tfile
356         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
357         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
358                 error "$tfile should be owned by GID $UID"
359         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
360         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
361                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
362 }
363 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
364
365 test_6g() {
366         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
367
368         test_mkdir $DIR/$tdir
369         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
370         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
371         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
372         test_mkdir $DIR/$tdir/d/subdir
373         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
374                 error "$tdir/d/subdir should be GID $RUNAS_GID"
375         if [[ $MDSCOUNT -gt 1 ]]; then
376                 # check remote dir sgid inherite
377                 $LFS mkdir -i 0 $DIR/$tdir.local ||
378                         error "mkdir $tdir.local failed"
379                 chmod g+s $DIR/$tdir.local ||
380                         error "chmod $tdir.local failed"
381                 chgrp $RUNAS_GID $DIR/$tdir.local ||
382                         error "chgrp $tdir.local failed"
383                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
384                         error "mkdir $tdir.remote failed"
385                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
386                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
387                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
388                         error "$tdir.remote should be mode 02755"
389         fi
390 }
391 run_test 6g "verify new dir in sgid dir inherits group"
392
393 test_6h() { # bug 7331
394         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
395
396         touch $DIR/$tfile || error "touch failed"
397         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
398         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
399                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
400         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
401                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
402 }
403 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
404
405 test_7a() {
406         test_mkdir $DIR/$tdir
407         $MCREATE $DIR/$tdir/$tfile
408         chmod 0666 $DIR/$tdir/$tfile
409         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
410                 error "$tdir/$tfile should be mode 0666"
411 }
412 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
413
414 test_7b() {
415         if [ ! -d $DIR/$tdir ]; then
416                 test_mkdir $DIR/$tdir
417         fi
418         $MCREATE $DIR/$tdir/$tfile
419         echo -n foo > $DIR/$tdir/$tfile
420         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
421         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
422 }
423 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
424
425 test_8() {
426         test_mkdir $DIR/$tdir
427         touch $DIR/$tdir/$tfile
428         chmod 0666 $DIR/$tdir/$tfile
429         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
430                 error "$tfile mode not 0666"
431 }
432 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
433
434 test_9() {
435         test_mkdir $DIR/$tdir
436         test_mkdir $DIR/$tdir/d2
437         test_mkdir $DIR/$tdir/d2/d3
438         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
439 }
440 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
441
442 test_10() {
443         test_mkdir $DIR/$tdir
444         test_mkdir $DIR/$tdir/d2
445         touch $DIR/$tdir/d2/$tfile
446         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
447                 error "$tdir/d2/$tfile not a file"
448 }
449 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
450
451 test_11() {
452         test_mkdir $DIR/$tdir
453         test_mkdir $DIR/$tdir/d2
454         chmod 0666 $DIR/$tdir/d2
455         chmod 0705 $DIR/$tdir/d2
456         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
457                 error "$tdir/d2 mode not 0705"
458 }
459 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
460
461 test_12() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         chmod 0666 $DIR/$tdir/$tfile
465         chmod 0654 $DIR/$tdir/$tfile
466         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
467                 error "$tdir/d2 mode not 0654"
468 }
469 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
470
471 test_13() {
472         test_mkdir $DIR/$tdir
473         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
474         >  $DIR/$tdir/$tfile
475         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
476                 error "$tdir/$tfile size not 0 after truncate"
477 }
478 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
479
480 test_14() {
481         test_mkdir $DIR/$tdir
482         touch $DIR/$tdir/$tfile
483         rm $DIR/$tdir/$tfile
484         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
485 }
486 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
487
488 test_15() {
489         test_mkdir $DIR/$tdir
490         touch $DIR/$tdir/$tfile
491         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
492         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
493                 error "$tdir/${tfile_2} not a file after rename"
494         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
495 }
496 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
497
498 test_16() {
499         test_mkdir $DIR/$tdir
500         touch $DIR/$tdir/$tfile
501         rm -rf $DIR/$tdir/$tfile
502         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
503 }
504 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
505
506 test_17a() {
507         test_mkdir $DIR/$tdir
508         touch $DIR/$tdir/$tfile
509         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
510         ls -l $DIR/$tdir
511         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
512                 error "$tdir/l-exist not a symlink"
513         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
514                 error "$tdir/l-exist not referencing a file"
515         rm -f $DIR/$tdir/l-exist
516         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
517 }
518 run_test 17a "symlinks: create, remove (real)"
519
520 test_17b() {
521         test_mkdir $DIR/$tdir
522         ln -s no-such-file $DIR/$tdir/l-dangle
523         ls -l $DIR/$tdir
524         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
525                 error "$tdir/l-dangle not referencing no-such-file"
526         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
527                 error "$tdir/l-dangle not referencing non-existent file"
528         rm -f $DIR/$tdir/l-dangle
529         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
530 }
531 run_test 17b "symlinks: create, remove (dangling)"
532
533 test_17c() { # bug 3440 - don't save failed open RPC for replay
534         test_mkdir $DIR/$tdir
535         ln -s foo $DIR/$tdir/$tfile
536         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
537 }
538 run_test 17c "symlinks: open dangling (should return error)"
539
540 test_17d() {
541         test_mkdir $DIR/$tdir
542         ln -s foo $DIR/$tdir/$tfile
543         touch $DIR/$tdir/$tfile || error "creating to new symlink"
544 }
545 run_test 17d "symlinks: create dangling"
546
547 test_17e() {
548         test_mkdir $DIR/$tdir
549         local foo=$DIR/$tdir/$tfile
550         ln -s $foo $foo || error "create symlink failed"
551         ls -l $foo || error "ls -l failed"
552         ls $foo && error "ls not failed" || true
553 }
554 run_test 17e "symlinks: create recursive symlink (should return error)"
555
556 test_17f() {
557         test_mkdir $DIR/$tdir
558         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
559         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
561         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
562         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
563         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
564         ls -l  $DIR/$tdir
565 }
566 run_test 17f "symlinks: long and very long symlink name"
567
568 # str_repeat(S, N) generate a string that is string S repeated N times
569 str_repeat() {
570         local s=$1
571         local n=$2
572         local ret=''
573         while [ $((n -= 1)) -ge 0 ]; do
574                 ret=$ret$s
575         done
576         echo $ret
577 }
578
579 # Long symlinks and LU-2241
580 test_17g() {
581         test_mkdir $DIR/$tdir
582         local TESTS="59 60 61 4094 4095"
583
584         # Fix for inode size boundary in 2.1.4
585         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
586                 TESTS="4094 4095"
587
588         # Patch not applied to 2.2 or 2.3 branches
589         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
590         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
591                 TESTS="4094 4095"
592
593         for i in $TESTS; do
594                 local SYMNAME=$(str_repeat 'x' $i)
595                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
596                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
597         done
598 }
599 run_test 17g "symlinks: really long symlink name and inode boundaries"
600
601 test_17h() { #bug 17378
602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
603         remote_mds_nodsh && skip "remote MDS with nodsh"
604
605         local mdt_idx
606
607         test_mkdir $DIR/$tdir
608         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
609         $LFS setstripe -c -1 $DIR/$tdir
610         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
611         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
612         touch $DIR/$tdir/$tfile || true
613 }
614 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
615
616 test_17i() { #bug 20018
617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
618         remote_mds_nodsh && skip "remote MDS with nodsh"
619
620         local foo=$DIR/$tdir/$tfile
621         local mdt_idx
622
623         test_mkdir -c1 $DIR/$tdir
624         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
625         ln -s $foo $foo || error "create symlink failed"
626 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
627         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
628         ls -l $foo && error "error not detected"
629         return 0
630 }
631 run_test 17i "don't panic on short symlink (should return error)"
632
633 test_17k() { #bug 22301
634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
635         [[ -z "$(which rsync 2>/dev/null)" ]] &&
636                 skip "no rsync command"
637         rsync --help | grep -q xattr ||
638                 skip_env "$(rsync --version | head -n1) does not support xattrs"
639         test_mkdir $DIR/$tdir
640         test_mkdir $DIR/$tdir.new
641         touch $DIR/$tdir/$tfile
642         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
643         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
644                 error "rsync failed with xattrs enabled"
645 }
646 run_test 17k "symlinks: rsync with xattrs enabled"
647
648 test_17l() { # LU-279
649         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
650                 skip "no getfattr command"
651
652         test_mkdir $DIR/$tdir
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
656                 # -h to not follow symlinks. -m '' to list all the xattrs.
657                 # grep to remove first line: '# file: $path'.
658                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
659                 do
660                         lgetxattr_size_check $path $xattr ||
661                                 error "lgetxattr_size_check $path $xattr failed"
662                 done
663         done
664 }
665 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
666
667 # LU-1540
668 test_17m() {
669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
670         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
671         remote_mds_nodsh && skip "remote MDS with nodsh"
672         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
673         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
674                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
675
676         local short_sym="0123456789"
677         local wdir=$DIR/$tdir
678         local i
679
680         test_mkdir $wdir
681         long_sym=$short_sym
682         # create a long symlink file
683         for ((i = 0; i < 4; ++i)); do
684                 long_sym=${long_sym}${long_sym}
685         done
686
687         echo "create 512 short and long symlink files under $wdir"
688         for ((i = 0; i < 256; ++i)); do
689                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
690                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
691         done
692
693         echo "erase them"
694         rm -f $wdir/*
695         sync
696         wait_delete_completed
697
698         echo "recreate the 512 symlink files with a shorter string"
699         for ((i = 0; i < 512; ++i)); do
700                 # rewrite the symlink file with a shorter string
701                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
702                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
703         done
704
705         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
706
707         echo "stop and checking mds${mds_index}:"
708         # e2fsck should not return error
709         stop mds${mds_index}
710         local devname=$(mdsdevname $mds_index)
711         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
712         rc=$?
713
714         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
715                 error "start mds${mds_index} failed"
716         df $MOUNT > /dev/null 2>&1
717         [ $rc -eq 0 ] ||
718                 error "e2fsck detected error for short/long symlink: rc=$rc"
719         rm -f $wdir/*
720 }
721 run_test 17m "run e2fsck against MDT which contains short/long symlink"
722
723 check_fs_consistency_17n() {
724         local mdt_index
725         local rc=0
726
727         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
728         # so it only check MDT1/MDT2 instead of all of MDTs.
729         for mdt_index in 1 2; do
730                 # e2fsck should not return error
731                 stop mds${mdt_index}
732                 local devname=$(mdsdevname $mdt_index)
733                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
734                         rc=$((rc + $?))
735
736                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
737                         error "mount mds$mdt_index failed"
738                 df $MOUNT > /dev/null 2>&1
739         done
740         return $rc
741 }
742
743 test_17n() {
744         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
746         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
747         remote_mds_nodsh && skip "remote MDS with nodsh"
748         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
749         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
750                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
751
752         local i
753
754         test_mkdir $DIR/$tdir
755         for ((i=0; i<10; i++)); do
756                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
757                         error "create remote dir error $i"
758                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
759                         error "create files under remote dir failed $i"
760         done
761
762         check_fs_consistency_17n ||
763                 error "e2fsck report error after create files under remote dir"
764
765         for ((i = 0; i < 10; i++)); do
766                 rm -rf $DIR/$tdir/remote_dir_${i} ||
767                         error "destroy remote dir error $i"
768         done
769
770         check_fs_consistency_17n ||
771                 error "e2fsck report error after unlink files under remote dir"
772
773         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
774                 skip "lustre < 2.4.50 does not support migrate mv"
775
776         for ((i = 0; i < 10; i++)); do
777                 mkdir -p $DIR/$tdir/remote_dir_${i}
778                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
779                         error "create files under remote dir failed $i"
780                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
781                         error "migrate remote dir error $i"
782         done
783         check_fs_consistency_17n || error "e2fsck report error after migration"
784
785         for ((i = 0; i < 10; i++)); do
786                 rm -rf $DIR/$tdir/remote_dir_${i} ||
787                         error "destroy remote dir error $i"
788         done
789
790         check_fs_consistency_17n || error "e2fsck report error after unlink"
791 }
792 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
793
794 test_17o() {
795         remote_mds_nodsh && skip "remote MDS with nodsh"
796         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
797                 skip "Need MDS version at least 2.3.64"
798
799         local wdir=$DIR/${tdir}o
800         local mdt_index
801         local rc=0
802
803         test_mkdir $wdir
804         touch $wdir/$tfile
805         mdt_index=$($LFS getstripe -m $wdir/$tfile)
806         mdt_index=$((mdt_index + 1))
807
808         cancel_lru_locks mdc
809         #fail mds will wait the failover finish then set
810         #following fail_loc to avoid interfer the recovery process.
811         fail mds${mdt_index}
812
813         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
814         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
815         ls -l $wdir/$tfile && rc=1
816         do_facet mds${mdt_index} lctl set_param fail_loc=0
817         [[ $rc -eq 0 ]] || error "stat file should fail"
818 }
819 run_test 17o "stat file with incompat LMA feature"
820
821 test_18() {
822         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
823         ls $DIR || error "Failed to ls $DIR: $?"
824 }
825 run_test 18 "touch .../f ; ls ... =============================="
826
827 test_19a() {
828         touch $DIR/$tfile
829         ls -l $DIR
830         rm $DIR/$tfile
831         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
832 }
833 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
834
835 test_19b() {
836         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
837 }
838 run_test 19b "ls -l .../f19 (should return error) =============="
839
840 test_19c() {
841         [ $RUNAS_ID -eq $UID ] &&
842                 skip_env "RUNAS_ID = UID = $UID -- skipping"
843
844         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
845 }
846 run_test 19c "$RUNAS touch .../f19 (should return error) =="
847
848 test_19d() {
849         cat $DIR/f19 && error || true
850 }
851 run_test 19d "cat .../f19 (should return error) =============="
852
853 test_20() {
854         touch $DIR/$tfile
855         rm $DIR/$tfile
856         touch $DIR/$tfile
857         rm $DIR/$tfile
858         touch $DIR/$tfile
859         rm $DIR/$tfile
860         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
861 }
862 run_test 20 "touch .../f ; ls -l ..."
863
864 test_21() {
865         test_mkdir $DIR/$tdir
866         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
867         ln -s dangle $DIR/$tdir/link
868         echo foo >> $DIR/$tdir/link
869         cat $DIR/$tdir/dangle
870         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
871         $CHECKSTAT -f -t file $DIR/$tdir/link ||
872                 error "$tdir/link not linked to a file"
873 }
874 run_test 21 "write to dangling link"
875
876 test_22() {
877         local wdir=$DIR/$tdir
878         test_mkdir $wdir
879         chown $RUNAS_ID:$RUNAS_GID $wdir
880         (cd $wdir || error "cd $wdir failed";
881                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
882                 $RUNAS tar xf -)
883         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
884         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
885         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
886                 error "checkstat -u failed"
887 }
888 run_test 22 "unpack tar archive as non-root user"
889
890 # was test_23
891 test_23a() {
892         test_mkdir $DIR/$tdir
893         local file=$DIR/$tdir/$tfile
894
895         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
896         openfile -f O_CREAT:O_EXCL $file &&
897                 error "$file recreate succeeded" || true
898 }
899 run_test 23a "O_CREAT|O_EXCL in subdir"
900
901 test_23b() { # bug 18988
902         test_mkdir $DIR/$tdir
903         local file=$DIR/$tdir/$tfile
904
905         rm -f $file
906         echo foo > $file || error "write filed"
907         echo bar >> $file || error "append filed"
908         $CHECKSTAT -s 8 $file || error "wrong size"
909         rm $file
910 }
911 run_test 23b "O_APPEND check"
912
913 # LU-9409, size with O_APPEND and tiny writes
914 test_23c() {
915         local file=$DIR/$tfile
916
917         # single dd
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
919         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
920         rm -f $file
921
922         # racing tiny writes
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
924         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
925         wait
926         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
927         rm -f $file
928
929         #racing tiny & normal writes
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
931         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
932         wait
933         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
934         rm -f $file
935
936         #racing tiny & normal writes 2, ugly numbers
937         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
938         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
939         wait
940         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
941         rm -f $file
942 }
943 run_test 23c "O_APPEND size checks for tiny writes"
944
945 # LU-11069 file offset is correct after appending writes
946 test_23d() {
947         local file=$DIR/$tfile
948         local offset
949
950         echo CentaurHauls > $file
951         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
952         if ((offset != 26)); then
953                 error "wrong offset, expected 26, got '$offset'"
954         fi
955 }
956 run_test 23d "file offset is correct after appending writes"
957
958 # rename sanity
959 test_24a() {
960         echo '-- same directory rename'
961         test_mkdir $DIR/$tdir
962         touch $DIR/$tdir/$tfile.1
963         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
964         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
965 }
966 run_test 24a "rename file to non-existent target"
967
968 test_24b() {
969         test_mkdir $DIR/$tdir
970         touch $DIR/$tdir/$tfile.{1,2}
971         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
972         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
973         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
974 }
975 run_test 24b "rename file to existing target"
976
977 test_24c() {
978         test_mkdir $DIR/$tdir
979         test_mkdir $DIR/$tdir/d$testnum.1
980         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
981         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
982         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
983 }
984 run_test 24c "rename directory to non-existent target"
985
986 test_24d() {
987         test_mkdir -c1 $DIR/$tdir
988         test_mkdir -c1 $DIR/$tdir/d$testnum.1
989         test_mkdir -c1 $DIR/$tdir/d$testnum.2
990         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
991         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
992         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
993 }
994 run_test 24d "rename directory to existing target"
995
996 test_24e() {
997         echo '-- cross directory renames --'
998         test_mkdir $DIR/R5a
999         test_mkdir $DIR/R5b
1000         touch $DIR/R5a/f
1001         mv $DIR/R5a/f $DIR/R5b/g
1002         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1003         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1004 }
1005 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1006
1007 test_24f() {
1008         test_mkdir $DIR/R6a
1009         test_mkdir $DIR/R6b
1010         touch $DIR/R6a/f $DIR/R6b/g
1011         mv $DIR/R6a/f $DIR/R6b/g
1012         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1013         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1014 }
1015 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1016
1017 test_24g() {
1018         test_mkdir $DIR/R7a
1019         test_mkdir $DIR/R7b
1020         test_mkdir $DIR/R7a/d
1021         mv $DIR/R7a/d $DIR/R7b/e
1022         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1023         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1024 }
1025 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1026
1027 test_24h() {
1028         test_mkdir -c1 $DIR/R8a
1029         test_mkdir -c1 $DIR/R8b
1030         test_mkdir -c1 $DIR/R8a/d
1031         test_mkdir -c1 $DIR/R8b/e
1032         mrename $DIR/R8a/d $DIR/R8b/e
1033         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1034         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1035 }
1036 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1037
1038 test_24i() {
1039         echo "-- rename error cases"
1040         test_mkdir $DIR/R9
1041         test_mkdir $DIR/R9/a
1042         touch $DIR/R9/f
1043         mrename $DIR/R9/f $DIR/R9/a
1044         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1045         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1046         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1047 }
1048 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1049
1050 test_24j() {
1051         test_mkdir $DIR/R10
1052         mrename $DIR/R10/f $DIR/R10/g
1053         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1054         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1055         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1056 }
1057 run_test 24j "source does not exist ============================"
1058
1059 test_24k() {
1060         test_mkdir $DIR/R11a
1061         test_mkdir $DIR/R11a/d
1062         touch $DIR/R11a/f
1063         mv $DIR/R11a/f $DIR/R11a/d
1064         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1065         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1066 }
1067 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1068
1069 # bug 2429 - rename foo foo foo creates invalid file
1070 test_24l() {
1071         f="$DIR/f24l"
1072         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1073 }
1074 run_test 24l "Renaming a file to itself ========================"
1075
1076 test_24m() {
1077         f="$DIR/f24m"
1078         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1079         # on ext3 this does not remove either the source or target files
1080         # though the "expected" operation would be to remove the source
1081         $CHECKSTAT -t file ${f} || error "${f} missing"
1082         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1083 }
1084 run_test 24m "Renaming a file to a hard link to itself ========="
1085
1086 test_24n() {
1087     f="$DIR/f24n"
1088     # this stats the old file after it was renamed, so it should fail
1089     touch ${f}
1090     $CHECKSTAT ${f} || error "${f} missing"
1091     mv ${f} ${f}.rename
1092     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1093     $CHECKSTAT -a ${f} || error "${f} exists"
1094 }
1095 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1096
1097 test_24o() {
1098         test_mkdir $DIR/$tdir
1099         rename_many -s random -v -n 10 $DIR/$tdir
1100 }
1101 run_test 24o "rename of files during htree split"
1102
1103 test_24p() {
1104         test_mkdir $DIR/R12a
1105         test_mkdir $DIR/R12b
1106         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1107         mrename $DIR/R12a $DIR/R12b
1108         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1109         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1110         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1111         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1112 }
1113 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1114
1115 cleanup_multiop_pause() {
1116         trap 0
1117         kill -USR1 $MULTIPID
1118 }
1119
1120 test_24q() {
1121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1122
1123         test_mkdir $DIR/R13a
1124         test_mkdir $DIR/R13b
1125         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1126         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1127         MULTIPID=$!
1128
1129         trap cleanup_multiop_pause EXIT
1130         mrename $DIR/R13a $DIR/R13b
1131         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1132         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1133         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1134         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1135         cleanup_multiop_pause
1136         wait $MULTIPID || error "multiop close failed"
1137 }
1138 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1139
1140 test_24r() { #bug 3789
1141         test_mkdir $DIR/R14a
1142         test_mkdir $DIR/R14a/b
1143         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1145         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1146 }
1147 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1148
1149 test_24s() {
1150         test_mkdir $DIR/R15a
1151         test_mkdir $DIR/R15a/b
1152         test_mkdir $DIR/R15a/b/c
1153         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1154         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1155         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1156 }
1157 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1158 test_24t() {
1159         test_mkdir $DIR/R16a
1160         test_mkdir $DIR/R16a/b
1161         test_mkdir $DIR/R16a/b/c
1162         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1163         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1164         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1165 }
1166 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1167
1168 test_24u() { # bug12192
1169         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1170         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1171 }
1172 run_test 24u "create stripe file"
1173
1174 simple_cleanup_common() {
1175         local createmany=$1
1176         local rc=0
1177
1178         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1179
1180         local start=$SECONDS
1181
1182         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1183         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1184         rc=$?
1185         wait_delete_completed
1186         echo "cleanup time $((SECONDS - start))"
1187         return $rc
1188 }
1189
1190 max_pages_per_rpc() {
1191         local mdtname="$(printf "MDT%04x" ${1:-0})"
1192         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1193 }
1194
1195 test_24v() {
1196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1197
1198         local nrfiles=${COUNT:-100000}
1199         local fname="$DIR/$tdir/$tfile"
1200
1201         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1202         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1203
1204         test_mkdir "$(dirname $fname)"
1205         # assume MDT0000 has the fewest inodes
1206         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1207         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1208         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1209
1210         stack_trap "simple_cleanup_common $nrfiles"
1211
1212         createmany -m "$fname" $nrfiles
1213
1214         cancel_lru_locks mdc
1215         lctl set_param mdc.*.stats clear
1216
1217         # was previously test_24D: LU-6101
1218         # readdir() returns correct number of entries after cursor reload
1219         local num_ls=$(ls $DIR/$tdir | wc -l)
1220         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1221         local num_all=$(ls -a $DIR/$tdir | wc -l)
1222         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1223                 [ $num_all -ne $((nrfiles + 2)) ]; then
1224                         error "Expected $nrfiles files, got $num_ls " \
1225                                 "($num_uniq unique $num_all .&..)"
1226         fi
1227         # LU-5 large readdir
1228         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1229         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1230         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1231         # take into account of overhead in lu_dirpage header and end mark in
1232         # each page, plus one in rpc_num calculation.
1233         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1234         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1235         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1236         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1237         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1238         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1239         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1240         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1241                 error "large readdir doesn't take effect: " \
1242                       "$mds_readpage should be about $rpc_max"
1243 }
1244 run_test 24v "list large directory (test hash collision, b=17560)"
1245
1246 test_24w() { # bug21506
1247         SZ1=234852
1248         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1249         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1250         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1251         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1252         [[ "$SZ1" -eq "$SZ2" ]] ||
1253                 error "Error reading at the end of the file $tfile"
1254 }
1255 run_test 24w "Reading a file larger than 4Gb"
1256
1257 test_24x() {
1258         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1260         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1261                 skip "Need MDS version at least 2.7.56"
1262
1263         local MDTIDX=1
1264         local remote_dir=$DIR/$tdir/remote_dir
1265
1266         test_mkdir $DIR/$tdir
1267         $LFS mkdir -i $MDTIDX $remote_dir ||
1268                 error "create remote directory failed"
1269
1270         test_mkdir $DIR/$tdir/src_dir
1271         touch $DIR/$tdir/src_file
1272         test_mkdir $remote_dir/tgt_dir
1273         touch $remote_dir/tgt_file
1274
1275         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1276                 error "rename dir cross MDT failed!"
1277
1278         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1279                 error "rename file cross MDT failed!"
1280
1281         touch $DIR/$tdir/ln_file
1282         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1283                 error "ln file cross MDT failed"
1284
1285         rm -rf $DIR/$tdir || error "Can not delete directories"
1286 }
1287 run_test 24x "cross MDT rename/link"
1288
1289 test_24y() {
1290         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1292
1293         local remote_dir=$DIR/$tdir/remote_dir
1294         local mdtidx=1
1295
1296         test_mkdir $DIR/$tdir
1297         $LFS mkdir -i $mdtidx $remote_dir ||
1298                 error "create remote directory failed"
1299
1300         test_mkdir $remote_dir/src_dir
1301         touch $remote_dir/src_file
1302         test_mkdir $remote_dir/tgt_dir
1303         touch $remote_dir/tgt_file
1304
1305         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1306                 error "rename subdir in the same remote dir failed!"
1307
1308         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1309                 error "rename files in the same remote dir failed!"
1310
1311         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1312                 error "link files in the same remote dir failed!"
1313
1314         rm -rf $DIR/$tdir || error "Can not delete directories"
1315 }
1316 run_test 24y "rename/link on the same dir should succeed"
1317
1318 test_24z() {
1319         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1320         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1321                 skip "Need MDS version at least 2.12.51"
1322
1323         local index
1324
1325         for index in 0 1; do
1326                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1327                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1328         done
1329
1330         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1331
1332         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1333         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1334
1335         local mdts=$(comma_list $(mdts_nodes))
1336
1337         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1338         stack_trap "do_nodes $mdts $LCTL \
1339                 set_param mdt.*.enable_remote_rename=1" EXIT
1340
1341         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1342
1343         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1344         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1345 }
1346 run_test 24z "cross-MDT rename is done as cp"
1347
1348 test_24A() { # LU-3182
1349         local NFILES=5000
1350
1351         test_mkdir $DIR/$tdir
1352         stack_trap "simple_cleanup_common $NFILES"
1353         createmany -m $DIR/$tdir/$tfile $NFILES
1354         local t=$(ls $DIR/$tdir | wc -l)
1355         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1356         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1357
1358         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1359                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1360 }
1361 run_test 24A "readdir() returns correct number of entries."
1362
1363 test_24B() { # LU-4805
1364         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1365
1366         local count
1367
1368         test_mkdir $DIR/$tdir
1369         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1370                 error "create striped dir failed"
1371
1372         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1373         [ $count -eq 2 ] || error "Expected 2, got $count"
1374
1375         touch $DIR/$tdir/striped_dir/a
1376
1377         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1378         [ $count -eq 3 ] || error "Expected 3, got $count"
1379
1380         touch $DIR/$tdir/striped_dir/.f
1381
1382         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1383         [ $count -eq 4 ] || error "Expected 4, got $count"
1384
1385         rm -rf $DIR/$tdir || error "Can not delete directories"
1386 }
1387 run_test 24B "readdir for striped dir return correct number of entries"
1388
1389 test_24C() {
1390         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1391
1392         mkdir $DIR/$tdir
1393         mkdir $DIR/$tdir/d0
1394         mkdir $DIR/$tdir/d1
1395
1396         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1397                 error "create striped dir failed"
1398
1399         cd $DIR/$tdir/d0/striped_dir
1400
1401         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1402         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1403         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1404
1405         [ "$d0_ino" = "$parent_ino" ] ||
1406                 error ".. wrong, expect $d0_ino, get $parent_ino"
1407
1408         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1409                 error "mv striped dir failed"
1410
1411         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1412
1413         [ "$d1_ino" = "$parent_ino" ] ||
1414                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1415 }
1416 run_test 24C "check .. in striped dir"
1417
1418 test_24E() {
1419         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1421
1422         mkdir -p $DIR/$tdir
1423         mkdir $DIR/$tdir/src_dir
1424         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1425                 error "create remote source failed"
1426
1427         touch $DIR/$tdir/src_dir/src_child/a
1428
1429         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1430                 error "create remote target dir failed"
1431
1432         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1433                 error "create remote target child failed"
1434
1435         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1436                 error "rename dir cross MDT failed!"
1437
1438         find $DIR/$tdir
1439
1440         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1441                 error "src_child still exists after rename"
1442
1443         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1444                 error "missing file(a) after rename"
1445
1446         rm -rf $DIR/$tdir || error "Can not delete directories"
1447 }
1448 run_test 24E "cross MDT rename/link"
1449
1450 test_24F () {
1451         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1452
1453         local repeats=1000
1454         [ "$SLOW" = "no" ] && repeats=100
1455
1456         mkdir -p $DIR/$tdir
1457
1458         echo "$repeats repeats"
1459         for ((i = 0; i < repeats; i++)); do
1460                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1461                 touch $DIR/$tdir/test/a || error "touch fails"
1462                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1463                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1464         done
1465
1466         true
1467 }
1468 run_test 24F "hash order vs readdir (LU-11330)"
1469
1470 test_24G () {
1471         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1472
1473         local ino1
1474         local ino2
1475
1476         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1477         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1478         touch $DIR/$tdir-0/f1 || error "touch f1"
1479         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1480         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1481         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1482         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1483         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1484 }
1485 run_test 24G "migrate symlink in rename"
1486
1487 test_24H() {
1488         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1489         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1490                 skip "MDT1 should be on another node"
1491
1492         test_mkdir -i 1 -c 1 $DIR/$tdir
1493 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1494         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1495         touch $DIR/$tdir/$tfile || error "touch failed"
1496 }
1497 run_test 24H "repeat FLD_QUERY rpc"
1498
1499 test_25a() {
1500         echo '== symlink sanity ============================================='
1501
1502         test_mkdir $DIR/d25
1503         ln -s d25 $DIR/s25
1504         touch $DIR/s25/foo ||
1505                 error "File creation in symlinked directory failed"
1506 }
1507 run_test 25a "create file in symlinked directory ==============="
1508
1509 test_25b() {
1510         [ ! -d $DIR/d25 ] && test_25a
1511         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1512 }
1513 run_test 25b "lookup file in symlinked directory ==============="
1514
1515 test_26a() {
1516         test_mkdir $DIR/d26
1517         test_mkdir $DIR/d26/d26-2
1518         ln -s d26/d26-2 $DIR/s26
1519         touch $DIR/s26/foo || error "File creation failed"
1520 }
1521 run_test 26a "multiple component symlink ======================="
1522
1523 test_26b() {
1524         test_mkdir -p $DIR/$tdir/d26-2
1525         ln -s $tdir/d26-2/foo $DIR/s26-2
1526         touch $DIR/s26-2 || error "File creation failed"
1527 }
1528 run_test 26b "multiple component symlink at end of lookup ======"
1529
1530 test_26c() {
1531         test_mkdir $DIR/d26.2
1532         touch $DIR/d26.2/foo
1533         ln -s d26.2 $DIR/s26.2-1
1534         ln -s s26.2-1 $DIR/s26.2-2
1535         ln -s s26.2-2 $DIR/s26.2-3
1536         chmod 0666 $DIR/s26.2-3/foo
1537 }
1538 run_test 26c "chain of symlinks"
1539
1540 # recursive symlinks (bug 439)
1541 test_26d() {
1542         ln -s d26-3/foo $DIR/d26-3
1543 }
1544 run_test 26d "create multiple component recursive symlink"
1545
1546 test_26e() {
1547         [ ! -h $DIR/d26-3 ] && test_26d
1548         rm $DIR/d26-3
1549 }
1550 run_test 26e "unlink multiple component recursive symlink"
1551
1552 # recursive symlinks (bug 7022)
1553 test_26f() {
1554         test_mkdir $DIR/$tdir
1555         test_mkdir $DIR/$tdir/$tfile
1556         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1557         test_mkdir -p lndir/bar1
1558         test_mkdir $DIR/$tdir/$tfile/$tfile
1559         cd $tfile                || error "cd $tfile failed"
1560         ln -s .. dotdot          || error "ln dotdot failed"
1561         ln -s dotdot/lndir lndir || error "ln lndir failed"
1562         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1563         output=`ls $tfile/$tfile/lndir/bar1`
1564         [ "$output" = bar1 ] && error "unexpected output"
1565         rm -r $tfile             || error "rm $tfile failed"
1566         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1567 }
1568 run_test 26f "rm -r of a directory which has recursive symlink"
1569
1570 test_27a() {
1571         test_mkdir $DIR/$tdir
1572         $LFS getstripe $DIR/$tdir
1573         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1574         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1575         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1576 }
1577 run_test 27a "one stripe file"
1578
1579 test_27b() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1581
1582         test_mkdir $DIR/$tdir
1583         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1584         $LFS getstripe -c $DIR/$tdir/$tfile
1585         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1586                 error "two-stripe file doesn't have two stripes"
1587
1588         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1589 }
1590 run_test 27b "create and write to two stripe file"
1591
1592 # 27c family tests specific striping, setstripe -o
1593 test_27ca() {
1594         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1595         test_mkdir -p $DIR/$tdir
1596         local osts="1"
1597
1598         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1599         $LFS getstripe -i $DIR/$tdir/$tfile
1600         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1601                 error "stripe not on specified OST"
1602
1603         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1604 }
1605 run_test 27ca "one stripe on specified OST"
1606
1607 test_27cb() {
1608         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1609         test_mkdir -p $DIR/$tdir
1610         local osts="1,0"
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1612         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1613         echo "$getstripe"
1614
1615         # Strip getstripe output to a space separated list of OSTs
1616         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1617                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1618         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1619                 error "stripes not on specified OSTs"
1620
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1622 }
1623 run_test 27cb "two stripes on specified OSTs"
1624
1625 test_27cc() {
1626         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1627         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1628                 skip "server does not support overstriping"
1629
1630         test_mkdir -p $DIR/$tdir
1631         local osts="0,0"
1632         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1633         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1634         echo "$getstripe"
1635
1636         # Strip getstripe output to a space separated list of OSTs
1637         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1638                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1639         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1640                 error "stripes not on specified OSTs"
1641
1642         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1643 }
1644 run_test 27cc "two stripes on the same OST"
1645
1646 test_27cd() {
1647         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1648         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1649                 skip "server does not support overstriping"
1650         test_mkdir -p $DIR/$tdir
1651         local osts="0,1,1,0"
1652         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1653         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1654         echo "$getstripe"
1655
1656         # Strip getstripe output to a space separated list of OSTs
1657         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1658                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1659         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1660                 error "stripes not on specified OSTs"
1661
1662         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1663 }
1664 run_test 27cd "four stripes on two OSTs"
1665
1666 test_27ce() {
1667         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1668                 skip_env "too many osts, skipping"
1669         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1670                 skip "server does not support overstriping"
1671         # We do one more stripe than we have OSTs
1672         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1673                 skip_env "ea_inode feature disabled"
1674
1675         test_mkdir -p $DIR/$tdir
1676         local osts=""
1677         for i in $(seq 0 $OSTCOUNT);
1678         do
1679                 osts=$osts"0"
1680                 if [ $i -ne $OSTCOUNT ]; then
1681                         osts=$osts","
1682                 fi
1683         done
1684         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1685         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1686         echo "$getstripe"
1687
1688         # Strip getstripe output to a space separated list of OSTs
1689         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1690                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1691         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1692                 error "stripes not on specified OSTs"
1693
1694         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1695 }
1696 run_test 27ce "more stripes than OSTs with -o"
1697
1698 test_27cf() {
1699         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1700         local pid=0
1701
1702         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1703         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1704         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1705         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1706                 error "failed to set $osp_proc=0"
1707
1708         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1709         pid=$!
1710         sleep 1
1711         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1712         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1713                 error "failed to set $osp_proc=1"
1714         wait $pid
1715         [[ $pid -ne 0 ]] ||
1716                 error "should return error due to $osp_proc=0"
1717 }
1718 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1719
1720 test_27d() {
1721         test_mkdir $DIR/$tdir
1722         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1723                 error "setstripe failed"
1724         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1725         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1726 }
1727 run_test 27d "create file with default settings"
1728
1729 test_27e() {
1730         # LU-5839 adds check for existed layout before setting it
1731         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1732                 skip "Need MDS version at least 2.7.56"
1733
1734         test_mkdir $DIR/$tdir
1735         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1736         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1737         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1738 }
1739 run_test 27e "setstripe existing file (should return error)"
1740
1741 test_27f() {
1742         test_mkdir $DIR/$tdir
1743         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1744                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1745         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1746                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1747         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1748         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1749 }
1750 run_test 27f "setstripe with bad stripe size (should return error)"
1751
1752 test_27g() {
1753         test_mkdir $DIR/$tdir
1754         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1755         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1756                 error "$DIR/$tdir/$tfile has object"
1757 }
1758 run_test 27g "$LFS getstripe with no objects"
1759
1760 test_27ga() {
1761         test_mkdir $DIR/$tdir
1762         touch $DIR/$tdir/$tfile || error "touch failed"
1763         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1764         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1765         local rc=$?
1766         (( rc == 2 )) || error "getstripe did not return ENOENT"
1767 }
1768 run_test 27ga "$LFS getstripe with missing file (should return error)"
1769
1770 test_27i() {
1771         test_mkdir $DIR/$tdir
1772         touch $DIR/$tdir/$tfile || error "touch failed"
1773         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1774                 error "missing objects"
1775 }
1776 run_test 27i "$LFS getstripe with some objects"
1777
1778 test_27j() {
1779         test_mkdir $DIR/$tdir
1780         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1781                 error "setstripe failed" || true
1782 }
1783 run_test 27j "setstripe with bad stripe offset (should return error)"
1784
1785 test_27k() { # bug 2844
1786         test_mkdir $DIR/$tdir
1787         local file=$DIR/$tdir/$tfile
1788         local ll_max_blksize=$((4 * 1024 * 1024))
1789         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1790         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1791         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1792         dd if=/dev/zero of=$file bs=4k count=1
1793         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1794         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1795 }
1796 run_test 27k "limit i_blksize for broken user apps"
1797
1798 test_27l() {
1799         mcreate $DIR/$tfile || error "creating file"
1800         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1801                 error "setstripe should have failed" || true
1802 }
1803 run_test 27l "check setstripe permissions (should return error)"
1804
1805 test_27m() {
1806         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1807
1808         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1809                 skip_env "multiple clients -- skipping"
1810
1811         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1812                    head -n1)
1813         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1814                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1815         fi
1816         stack_trap simple_cleanup_common
1817         test_mkdir $DIR/$tdir
1818         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1819         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1820                 error "dd should fill OST0"
1821         i=2
1822         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1823                 i=$((i + 1))
1824                 [ $i -gt 256 ] && break
1825         done
1826         i=$((i + 1))
1827         touch $DIR/$tdir/$tfile.$i
1828         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1829             awk '{print $1}'| grep -w "0") ] &&
1830                 error "OST0 was full but new created file still use it"
1831         i=$((i + 1))
1832         touch $DIR/$tdir/$tfile.$i
1833         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1834             awk '{print $1}'| grep -w "0") ] &&
1835                 error "OST0 was full but new created file still use it" || true
1836 }
1837 run_test 27m "create file while OST0 was full"
1838
1839 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1840 # if the OST isn't full anymore.
1841 reset_enospc() {
1842         local ostidx=${1:-""}
1843         local delay
1844         local ready
1845         local get_prealloc
1846
1847         local list=$(comma_list $(osts_nodes))
1848         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1849
1850         do_nodes $list lctl set_param fail_loc=0
1851         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1852         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1853                 awk '{print $1 * 2;exit;}')
1854         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1855                         grep -v \"^0$\""
1856         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1857 }
1858
1859 test_27n() {
1860         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1862         remote_mds_nodsh && skip "remote MDS with nodsh"
1863         remote_ost_nodsh && skip "remote OST with nodsh"
1864
1865         reset_enospc
1866         rm -f $DIR/$tdir/$tfile
1867         exhaust_precreations 0 0x80000215
1868         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1869         touch $DIR/$tdir/$tfile || error "touch failed"
1870         $LFS getstripe $DIR/$tdir/$tfile
1871         reset_enospc
1872 }
1873 run_test 27n "create file with some full OSTs"
1874
1875 test_27o() {
1876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1878         remote_mds_nodsh && skip "remote MDS with nodsh"
1879         remote_ost_nodsh && skip "remote OST with nodsh"
1880
1881         reset_enospc
1882         rm -f $DIR/$tdir/$tfile
1883         exhaust_all_precreations 0x215
1884
1885         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1886
1887         reset_enospc
1888         rm -rf $DIR/$tdir/*
1889 }
1890 run_test 27o "create file with all full OSTs (should error)"
1891
1892 function create_and_checktime() {
1893         local fname=$1
1894         local loops=$2
1895         local i
1896
1897         for ((i=0; i < $loops; i++)); do
1898                 local start=$SECONDS
1899                 multiop $fname-$i Oc
1900                 ((SECONDS-start < TIMEOUT)) ||
1901                         error "creation took " $((SECONDS-$start)) && return 1
1902         done
1903 }
1904
1905 test_27oo() {
1906         local mdts=$(comma_list $(mdts_nodes))
1907
1908         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1909                 skip "Need MDS version at least 2.13.57"
1910
1911         local f0=$DIR/${tfile}-0
1912         local f1=$DIR/${tfile}-1
1913
1914         wait_delete_completed
1915
1916         # refill precreated objects
1917         $LFS setstripe -i0 -c1 $f0
1918
1919         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1920         # force QoS allocation policy
1921         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1922         stack_trap "do_nodes $mdts $LCTL set_param \
1923                 lov.*.qos_threshold_rr=$saved" EXIT
1924         sleep_maxage
1925
1926         # one OST is unavailable, but still have few objects preallocated
1927         stop ost1
1928         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1929                 rm -rf $f1 $DIR/$tdir*" EXIT
1930
1931         for ((i=0; i < 7; i++)); do
1932                 mkdir $DIR/$tdir$i || error "can't create dir"
1933                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1934                         error "can't set striping"
1935         done
1936         for ((i=0; i < 7; i++)); do
1937                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1938         done
1939         wait
1940 }
1941 run_test 27oo "don't let few threads to reserve too many objects"
1942
1943 test_27p() {
1944         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1946         remote_mds_nodsh && skip "remote MDS with nodsh"
1947         remote_ost_nodsh && skip "remote OST with nodsh"
1948
1949         reset_enospc
1950         rm -f $DIR/$tdir/$tfile
1951         test_mkdir $DIR/$tdir
1952
1953         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1954         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1955         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1956
1957         exhaust_precreations 0 0x80000215
1958         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1959         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1960         $LFS getstripe $DIR/$tdir/$tfile
1961
1962         reset_enospc
1963 }
1964 run_test 27p "append to a truncated file with some full OSTs"
1965
1966 test_27q() {
1967         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1969         remote_mds_nodsh && skip "remote MDS with nodsh"
1970         remote_ost_nodsh && skip "remote OST with nodsh"
1971
1972         reset_enospc
1973         rm -f $DIR/$tdir/$tfile
1974
1975         mkdir_on_mdt0 $DIR/$tdir
1976         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1977         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1978                 error "truncate $DIR/$tdir/$tfile failed"
1979         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1980
1981         exhaust_all_precreations 0x215
1982
1983         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1984         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1985
1986         reset_enospc
1987 }
1988 run_test 27q "append to truncated file with all OSTs full (should error)"
1989
1990 test_27r() {
1991         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1993         remote_mds_nodsh && skip "remote MDS with nodsh"
1994         remote_ost_nodsh && skip "remote OST with nodsh"
1995
1996         reset_enospc
1997         rm -f $DIR/$tdir/$tfile
1998         exhaust_precreations 0 0x80000215
1999
2000         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2001
2002         reset_enospc
2003 }
2004 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2005
2006 test_27s() { # bug 10725
2007         test_mkdir $DIR/$tdir
2008         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2009         local stripe_count=0
2010         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2011         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2012                 error "stripe width >= 2^32 succeeded" || true
2013
2014 }
2015 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2016
2017 test_27t() { # bug 10864
2018         WDIR=$(pwd)
2019         WLFS=$(which lfs)
2020         cd $DIR
2021         touch $tfile
2022         $WLFS getstripe $tfile
2023         cd $WDIR
2024 }
2025 run_test 27t "check that utils parse path correctly"
2026
2027 test_27u() { # bug 4900
2028         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2029         remote_mds_nodsh && skip "remote MDS with nodsh"
2030
2031         local index
2032         local list=$(comma_list $(mdts_nodes))
2033
2034 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2035         do_nodes $list $LCTL set_param fail_loc=0x139
2036         test_mkdir -p $DIR/$tdir
2037         stack_trap "simple_cleanup_common 1000"
2038         createmany -o $DIR/$tdir/$tfile 1000
2039         do_nodes $list $LCTL set_param fail_loc=0
2040
2041         TLOG=$TMP/$tfile.getstripe
2042         $LFS getstripe $DIR/$tdir > $TLOG
2043         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2044         [[ $OBJS -gt 0 ]] &&
2045                 error "$OBJS objects created on OST-0. See $TLOG" ||
2046                 rm -f $TLOG
2047 }
2048 run_test 27u "skip object creation on OSC w/o objects"
2049
2050 test_27v() { # bug 4900
2051         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2053         remote_mds_nodsh && skip "remote MDS with nodsh"
2054         remote_ost_nodsh && skip "remote OST with nodsh"
2055
2056         exhaust_all_precreations 0x215
2057         reset_enospc
2058
2059         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2060
2061         touch $DIR/$tdir/$tfile
2062         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2063         # all except ost1
2064         for (( i=1; i < OSTCOUNT; i++ )); do
2065                 do_facet ost$i lctl set_param fail_loc=0x705
2066         done
2067         local START=`date +%s`
2068         createmany -o $DIR/$tdir/$tfile 32
2069
2070         local FINISH=`date +%s`
2071         local TIMEOUT=`lctl get_param -n timeout`
2072         local PROCESS=$((FINISH - START))
2073         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2074                error "$FINISH - $START >= $TIMEOUT / 2"
2075         sleep $((TIMEOUT / 2 - PROCESS))
2076         reset_enospc
2077 }
2078 run_test 27v "skip object creation on slow OST"
2079
2080 test_27w() { # bug 10997
2081         test_mkdir $DIR/$tdir
2082         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2083         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2084                 error "stripe size $size != 65536" || true
2085         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2086                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2087 }
2088 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2089
2090 test_27wa() {
2091         [[ $OSTCOUNT -lt 2 ]] &&
2092                 skip_env "skipping multiple stripe count/offset test"
2093
2094         test_mkdir $DIR/$tdir
2095         for i in $(seq 1 $OSTCOUNT); do
2096                 offset=$((i - 1))
2097                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2098                         error "setstripe -c $i -i $offset failed"
2099                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2100                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2101                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2102                 [ $index -ne $offset ] &&
2103                         error "stripe offset $index != $offset" || true
2104         done
2105 }
2106 run_test 27wa "check $LFS setstripe -c -i options"
2107
2108 test_27x() {
2109         remote_ost_nodsh && skip "remote OST with nodsh"
2110         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2112
2113         OFFSET=$(($OSTCOUNT - 1))
2114         OSTIDX=0
2115         local OST=$(ostname_from_index $OSTIDX)
2116
2117         test_mkdir $DIR/$tdir
2118         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2119         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2120         sleep_maxage
2121         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2122         for i in $(seq 0 $OFFSET); do
2123                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2124                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2125                 error "OST0 was degraded but new created file still use it"
2126         done
2127         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2128 }
2129 run_test 27x "create files while OST0 is degraded"
2130
2131 test_27y() {
2132         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2133         remote_mds_nodsh && skip "remote MDS with nodsh"
2134         remote_ost_nodsh && skip "remote OST with nodsh"
2135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2136
2137         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2138         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2139                 osp.$mdtosc.prealloc_last_id)
2140         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2141                 osp.$mdtosc.prealloc_next_id)
2142         local fcount=$((last_id - next_id))
2143         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2144         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2145
2146         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2147                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2148         local OST_DEACTIVE_IDX=-1
2149         local OSC
2150         local OSTIDX
2151         local OST
2152
2153         for OSC in $MDS_OSCS; do
2154                 OST=$(osc_to_ost $OSC)
2155                 OSTIDX=$(index_from_ostuuid $OST)
2156                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2157                         OST_DEACTIVE_IDX=$OSTIDX
2158                 fi
2159                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2160                         echo $OSC "is Deactivated:"
2161                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2162                 fi
2163         done
2164
2165         OSTIDX=$(index_from_ostuuid $OST)
2166         test_mkdir $DIR/$tdir
2167         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2168
2169         for OSC in $MDS_OSCS; do
2170                 OST=$(osc_to_ost $OSC)
2171                 OSTIDX=$(index_from_ostuuid $OST)
2172                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2173                         echo $OST "is degraded:"
2174                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2175                                                 obdfilter.$OST.degraded=1
2176                 fi
2177         done
2178
2179         sleep_maxage
2180         createmany -o $DIR/$tdir/$tfile $fcount
2181
2182         for OSC in $MDS_OSCS; do
2183                 OST=$(osc_to_ost $OSC)
2184                 OSTIDX=$(index_from_ostuuid $OST)
2185                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2186                         echo $OST "is recovered from degraded:"
2187                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2188                                                 obdfilter.$OST.degraded=0
2189                 else
2190                         do_facet $SINGLEMDS lctl --device %$OSC activate
2191                 fi
2192         done
2193
2194         # all osp devices get activated, hence -1 stripe count restored
2195         local stripe_count=0
2196
2197         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2198         # devices get activated.
2199         sleep_maxage
2200         $LFS setstripe -c -1 $DIR/$tfile
2201         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2202         rm -f $DIR/$tfile
2203         [ $stripe_count -ne $OSTCOUNT ] &&
2204                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2205         return 0
2206 }
2207 run_test 27y "create files while OST0 is degraded and the rest inactive"
2208
2209 check_seq_oid()
2210 {
2211         log "check file $1"
2212
2213         lmm_count=$($LFS getstripe -c $1)
2214         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2215         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2216
2217         local old_ifs="$IFS"
2218         IFS=$'[:]'
2219         fid=($($LFS path2fid $1))
2220         IFS="$old_ifs"
2221
2222         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2223         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2224
2225         # compare lmm_seq and lu_fid->f_seq
2226         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2227         # compare lmm_object_id and lu_fid->oid
2228         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2229
2230         # check the trusted.fid attribute of the OST objects of the file
2231         local have_obdidx=false
2232         local stripe_nr=0
2233         $LFS getstripe $1 | while read obdidx oid hex seq; do
2234                 # skip lines up to and including "obdidx"
2235                 [ -z "$obdidx" ] && break
2236                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2237                 $have_obdidx || continue
2238
2239                 local ost=$((obdidx + 1))
2240                 local dev=$(ostdevname $ost)
2241                 local oid_hex
2242
2243                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2244
2245                 seq=$(echo $seq | sed -e "s/^0x//g")
2246                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2247                         oid_hex=$(echo $oid)
2248                 else
2249                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2250                 fi
2251                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2252
2253                 local ff=""
2254                 #
2255                 # Don't unmount/remount the OSTs if we don't need to do that.
2256                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2257                 # update too, until that use mount/ll_decode_filter_fid/mount.
2258                 # Re-enable when debugfs will understand new filter_fid.
2259                 #
2260                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2261                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2262                                 $dev 2>/dev/null" | grep "parent=")
2263                 fi
2264                 if [ -z "$ff" ]; then
2265                         stop ost$ost
2266                         mount_fstype ost$ost
2267                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2268                                 $(facet_mntpt ost$ost)/$obj_file)
2269                         unmount_fstype ost$ost
2270                         start ost$ost $dev $OST_MOUNT_OPTS
2271                         clients_up
2272                 fi
2273
2274                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2275
2276                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2277
2278                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2279                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2280                 #
2281                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2282                 #       stripe_size=1048576 component_id=1 component_start=0 \
2283                 #       component_end=33554432
2284                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2285                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2286                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2287                 local ff_pstripe
2288                 if grep -q 'stripe=' <<<$ff; then
2289                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2290                 else
2291                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2292                         # into f_ver in this case.  See comment on ff_parent.
2293                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2294                 fi
2295
2296                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2297                 [ $ff_pseq = $lmm_seq ] ||
2298                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2299                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2300                 [ $ff_poid = $lmm_oid ] ||
2301                         error "FF parent OID $ff_poid != $lmm_oid"
2302                 (($ff_pstripe == $stripe_nr)) ||
2303                         error "FF stripe $ff_pstripe != $stripe_nr"
2304
2305                 stripe_nr=$((stripe_nr + 1))
2306                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2307                         continue
2308                 if grep -q 'stripe_count=' <<<$ff; then
2309                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2310                                             -e 's/ .*//' <<<$ff)
2311                         [ $lmm_count = $ff_scnt ] ||
2312                                 error "FF stripe count $lmm_count != $ff_scnt"
2313                 fi
2314         done
2315 }
2316
2317 test_27z() {
2318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2319         remote_ost_nodsh && skip "remote OST with nodsh"
2320
2321         test_mkdir $DIR/$tdir
2322         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2323                 { error "setstripe -c -1 failed"; return 1; }
2324         # We need to send a write to every object to get parent FID info set.
2325         # This _should_ also work for setattr, but does not currently.
2326         # touch $DIR/$tdir/$tfile-1 ||
2327         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2328                 { error "dd $tfile-1 failed"; return 2; }
2329         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2330                 { error "setstripe -c -1 failed"; return 3; }
2331         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2332                 { error "dd $tfile-2 failed"; return 4; }
2333
2334         # make sure write RPCs have been sent to OSTs
2335         sync; sleep 5; sync
2336
2337         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2338         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2339 }
2340 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2341
2342 test_27A() { # b=19102
2343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2344
2345         save_layout_restore_at_exit $MOUNT
2346         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2347         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2348                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2349         local default_size=$($LFS getstripe -S $MOUNT)
2350         local default_offset=$($LFS getstripe -i $MOUNT)
2351         local dsize=$(do_facet $SINGLEMDS \
2352                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2353         [ $default_size -eq $dsize ] ||
2354                 error "stripe size $default_size != $dsize"
2355         [ $default_offset -eq -1 ] ||
2356                 error "stripe offset $default_offset != -1"
2357 }
2358 run_test 27A "check filesystem-wide default LOV EA values"
2359
2360 test_27B() { # LU-2523
2361         test_mkdir $DIR/$tdir
2362         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2363         touch $DIR/$tdir/f0
2364         # open f1 with O_LOV_DELAY_CREATE
2365         # rename f0 onto f1
2366         # call setstripe ioctl on open file descriptor for f1
2367         # close
2368         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2369                 $DIR/$tdir/f0
2370
2371         rm -f $DIR/$tdir/f1
2372         # open f1 with O_LOV_DELAY_CREATE
2373         # unlink f1
2374         # call setstripe ioctl on open file descriptor for f1
2375         # close
2376         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2377
2378         # Allow multiop to fail in imitation of NFS's busted semantics.
2379         true
2380 }
2381 run_test 27B "call setstripe on open unlinked file/rename victim"
2382
2383 # 27C family tests full striping and overstriping
2384 test_27Ca() { #LU-2871
2385         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2386
2387         declare -a ost_idx
2388         local index
2389         local found
2390         local i
2391         local j
2392
2393         test_mkdir $DIR/$tdir
2394         cd $DIR/$tdir
2395         for i in $(seq 0 $((OSTCOUNT - 1))); do
2396                 # set stripe across all OSTs starting from OST$i
2397                 $LFS setstripe -i $i -c -1 $tfile$i
2398                 # get striping information
2399                 ost_idx=($($LFS getstripe $tfile$i |
2400                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2401                 echo "OST Index: ${ost_idx[*]}"
2402
2403                 # check the layout
2404                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2405                         error "${#ost_idx[@]} != $OSTCOUNT"
2406
2407                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2408                         found=0
2409                         for j in "${ost_idx[@]}"; do
2410                                 if [ $index -eq $j ]; then
2411                                         found=1
2412                                         break
2413                                 fi
2414                         done
2415                         [ $found = 1 ] ||
2416                                 error "Can not find $index in ${ost_idx[*]}"
2417                 done
2418         done
2419 }
2420 run_test 27Ca "check full striping across all OSTs"
2421
2422 test_27Cb() {
2423         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2424                 skip "server does not support overstriping"
2425         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2426                 skip_env "too many osts, skipping"
2427
2428         test_mkdir -p $DIR/$tdir
2429         local setcount=$(($OSTCOUNT * 2))
2430         [ $setcount -lt 160 ] || large_xattr_enabled ||
2431                 skip_env "ea_inode feature disabled"
2432
2433         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2434                 error "setstripe failed"
2435
2436         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2437         [ $count -eq $setcount ] ||
2438                 error "stripe count $count, should be $setcount"
2439
2440         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2441                 error "overstriped should be set in pattern"
2442
2443         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2444                 error "dd failed"
2445 }
2446 run_test 27Cb "more stripes than OSTs with -C"
2447
2448 test_27Cc() {
2449         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2450                 skip "server does not support overstriping"
2451         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2452
2453         test_mkdir -p $DIR/$tdir
2454         local setcount=$(($OSTCOUNT - 1))
2455
2456         [ $setcount -lt 160 ] || large_xattr_enabled ||
2457                 skip_env "ea_inode feature disabled"
2458
2459         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2460                 error "setstripe failed"
2461
2462         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2463         [ $count -eq $setcount ] ||
2464                 error "stripe count $count, should be $setcount"
2465
2466         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2467                 error "overstriped should not be set in pattern"
2468
2469         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2470                 error "dd failed"
2471 }
2472 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2473
2474 test_27Cd() {
2475         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2476                 skip "server does not support overstriping"
2477         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2478         large_xattr_enabled || skip_env "ea_inode feature disabled"
2479
2480         test_mkdir -p $DIR/$tdir
2481         local setcount=$LOV_MAX_STRIPE_COUNT
2482
2483         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2484                 error "setstripe failed"
2485
2486         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2487         [ $count -eq $setcount ] ||
2488                 error "stripe count $count, should be $setcount"
2489
2490         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2491                 error "overstriped should be set in pattern"
2492
2493         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2494                 error "dd failed"
2495
2496         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2497 }
2498 run_test 27Cd "test maximum stripe count"
2499
2500 test_27Ce() {
2501         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2502                 skip "server does not support overstriping"
2503         test_mkdir -p $DIR/$tdir
2504
2505         pool_add $TESTNAME || error "Pool creation failed"
2506         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2507
2508         local setcount=8
2509
2510         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2511                 error "setstripe failed"
2512
2513         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2514         [ $count -eq $setcount ] ||
2515                 error "stripe count $count, should be $setcount"
2516
2517         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2518                 error "overstriped should be set in pattern"
2519
2520         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2521                 error "dd failed"
2522
2523         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2524 }
2525 run_test 27Ce "test pool with overstriping"
2526
2527 test_27Cf() {
2528         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2529                 skip "server does not support overstriping"
2530         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2531                 skip_env "too many osts, skipping"
2532
2533         test_mkdir -p $DIR/$tdir
2534
2535         local setcount=$(($OSTCOUNT * 2))
2536         [ $setcount -lt 160 ] || large_xattr_enabled ||
2537                 skip_env "ea_inode feature disabled"
2538
2539         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2540                 error "setstripe failed"
2541
2542         echo 1 > $DIR/$tdir/$tfile
2543
2544         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2545         [ $count -eq $setcount ] ||
2546                 error "stripe count $count, should be $setcount"
2547
2548         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2549                 error "overstriped should be set in pattern"
2550
2551         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2552                 error "dd failed"
2553
2554         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2555 }
2556 run_test 27Cf "test default inheritance with overstriping"
2557
2558 test_27D() {
2559         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2560         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2561         remote_mds_nodsh && skip "remote MDS with nodsh"
2562
2563         local POOL=${POOL:-testpool}
2564         local first_ost=0
2565         local last_ost=$(($OSTCOUNT - 1))
2566         local ost_step=1
2567         local ost_list=$(seq $first_ost $ost_step $last_ost)
2568         local ost_range="$first_ost $last_ost $ost_step"
2569
2570         test_mkdir $DIR/$tdir
2571         pool_add $POOL || error "pool_add failed"
2572         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2573
2574         local skip27D
2575         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2576                 skip27D+="-s 29"
2577         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2578                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2579                         skip27D+=" -s 30,31"
2580         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2581           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2582                 skip27D+=" -s 32,33"
2583         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2584                 skip27D+=" -s 34"
2585         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2586                 error "llapi_layout_test failed"
2587
2588         destroy_test_pools || error "destroy test pools failed"
2589 }
2590 run_test 27D "validate llapi_layout API"
2591
2592 # Verify that default_easize is increased from its initial value after
2593 # accessing a widely striped file.
2594 test_27E() {
2595         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2596         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2597                 skip "client does not have LU-3338 fix"
2598
2599         # 72 bytes is the minimum space required to store striping
2600         # information for a file striped across one OST:
2601         # (sizeof(struct lov_user_md_v3) +
2602         #  sizeof(struct lov_user_ost_data_v1))
2603         local min_easize=72
2604         $LCTL set_param -n llite.*.default_easize $min_easize ||
2605                 error "lctl set_param failed"
2606         local easize=$($LCTL get_param -n llite.*.default_easize)
2607
2608         [ $easize -eq $min_easize ] ||
2609                 error "failed to set default_easize"
2610
2611         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2612                 error "setstripe failed"
2613         # In order to ensure stat() call actually talks to MDS we need to
2614         # do something drastic to this file to shake off all lock, e.g.
2615         # rename it (kills lookup lock forcing cache cleaning)
2616         mv $DIR/$tfile $DIR/${tfile}-1
2617         ls -l $DIR/${tfile}-1
2618         rm $DIR/${tfile}-1
2619
2620         easize=$($LCTL get_param -n llite.*.default_easize)
2621
2622         [ $easize -gt $min_easize ] ||
2623                 error "default_easize not updated"
2624 }
2625 run_test 27E "check that default extended attribute size properly increases"
2626
2627 test_27F() { # LU-5346/LU-7975
2628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2629         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2630         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2631                 skip "Need MDS version at least 2.8.51"
2632         remote_ost_nodsh && skip "remote OST with nodsh"
2633
2634         test_mkdir $DIR/$tdir
2635         rm -f $DIR/$tdir/f0
2636         $LFS setstripe -c 2 $DIR/$tdir
2637
2638         # stop all OSTs to reproduce situation for LU-7975 ticket
2639         for num in $(seq $OSTCOUNT); do
2640                 stop ost$num
2641         done
2642
2643         # open/create f0 with O_LOV_DELAY_CREATE
2644         # truncate f0 to a non-0 size
2645         # close
2646         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2647
2648         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2649         # open/write it again to force delayed layout creation
2650         cat /etc/hosts > $DIR/$tdir/f0 &
2651         catpid=$!
2652
2653         # restart OSTs
2654         for num in $(seq $OSTCOUNT); do
2655                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2656                         error "ost$num failed to start"
2657         done
2658
2659         wait $catpid || error "cat failed"
2660
2661         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2662         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2663                 error "wrong stripecount"
2664
2665 }
2666 run_test 27F "Client resend delayed layout creation with non-zero size"
2667
2668 test_27G() { #LU-10629
2669         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2670                 skip "Need MDS version at least 2.11.51"
2671         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2672         remote_mds_nodsh && skip "remote MDS with nodsh"
2673         local POOL=${POOL:-testpool}
2674         local ostrange="0 0 1"
2675
2676         test_mkdir $DIR/$tdir
2677         touch $DIR/$tdir/$tfile.nopool
2678         pool_add $POOL || error "pool_add failed"
2679         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2680         $LFS setstripe -p $POOL $DIR/$tdir
2681
2682         local pool=$($LFS getstripe -p $DIR/$tdir)
2683
2684         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2685         touch $DIR/$tdir/$tfile.default
2686         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2687         $LFS find $DIR/$tdir -type f --pool $POOL
2688         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2689         [[ "$found" == "2" ]] ||
2690                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2691
2692         $LFS setstripe -d $DIR/$tdir
2693
2694         pool=$($LFS getstripe -p -d $DIR/$tdir)
2695
2696         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2697 }
2698 run_test 27G "Clear OST pool from stripe"
2699
2700 test_27H() {
2701         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2702                 skip "Need MDS version newer than 2.11.54"
2703         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2704         test_mkdir $DIR/$tdir
2705         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2706         touch $DIR/$tdir/$tfile
2707         $LFS getstripe -c $DIR/$tdir/$tfile
2708         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2709                 error "two-stripe file doesn't have two stripes"
2710
2711         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2712         $LFS getstripe -y $DIR/$tdir/$tfile
2713         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2714              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2715                 error "expected l_ost_idx: [02]$ not matched"
2716
2717         # make sure ost list has been cleared
2718         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2719         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2720                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2721         touch $DIR/$tdir/f3
2722         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2723 }
2724 run_test 27H "Set specific OSTs stripe"
2725
2726 test_27I() {
2727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2728         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2729         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2730                 skip "Need MDS version newer than 2.12.52"
2731         local pool=$TESTNAME
2732         local ostrange="1 1 1"
2733
2734         save_layout_restore_at_exit $MOUNT
2735         $LFS setstripe -c 2 -i 0 $MOUNT
2736         pool_add $pool || error "pool_add failed"
2737         pool_add_targets $pool $ostrange ||
2738                 error "pool_add_targets failed"
2739         test_mkdir $DIR/$tdir
2740         $LFS setstripe -p $pool $DIR/$tdir
2741         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2742         $LFS getstripe $DIR/$tdir/$tfile
2743 }
2744 run_test 27I "check that root dir striping does not break parent dir one"
2745
2746 test_27J() {
2747         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2748                 skip "Need MDS version newer than 2.12.51"
2749
2750         test_mkdir $DIR/$tdir
2751         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2752         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2753
2754         # create foreign file (raw way)
2755         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2756                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2757
2758         ! $LFS setstripe --foreign --flags foo \
2759                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2760                         error "creating $tfile with '--flags foo' should fail"
2761
2762         ! $LFS setstripe --foreign --flags 0xffffffff \
2763                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2764                         error "creating $tfile w/ 0xffffffff flags should fail"
2765
2766         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2767                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2768
2769         # verify foreign file (raw way)
2770         parse_foreign_file -f $DIR/$tdir/$tfile |
2771                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2773         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2774                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2775         parse_foreign_file -f $DIR/$tdir/$tfile |
2776                 grep "lov_foreign_size: 73" ||
2777                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2778         parse_foreign_file -f $DIR/$tdir/$tfile |
2779                 grep "lov_foreign_type: 1" ||
2780                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2781         parse_foreign_file -f $DIR/$tdir/$tfile |
2782                 grep "lov_foreign_flags: 0x0000DA08" ||
2783                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2784         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2785                 grep "lov_foreign_value: 0x" |
2786                 sed -e 's/lov_foreign_value: 0x//')
2787         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2788         [[ $lov = ${lov2// /} ]] ||
2789                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2790
2791         # create foreign file (lfs + API)
2792         $LFS setstripe --foreign=none --flags 0xda08 \
2793                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2794                 error "$DIR/$tdir/${tfile}2: create failed"
2795
2796         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2797                 grep "lfm_magic:.*0x0BD70BD0" ||
2798                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2799         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2800         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2803                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2804         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2805                 grep "lfm_flags:.*0x0000DA08" ||
2806                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2807         $LFS getstripe $DIR/$tdir/${tfile}2 |
2808                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2809                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2810
2811         # modify striping should fail
2812         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2813                 error "$DIR/$tdir/$tfile: setstripe should fail"
2814         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2815                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2816
2817         # R/W should fail
2818         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2819         cat $DIR/$tdir/${tfile}2 &&
2820                 error "$DIR/$tdir/${tfile}2: read should fail"
2821         cat /etc/passwd > $DIR/$tdir/$tfile &&
2822                 error "$DIR/$tdir/$tfile: write should fail"
2823         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2824                 error "$DIR/$tdir/${tfile}2: write should fail"
2825
2826         # chmod should work
2827         chmod 222 $DIR/$tdir/$tfile ||
2828                 error "$DIR/$tdir/$tfile: chmod failed"
2829         chmod 222 $DIR/$tdir/${tfile}2 ||
2830                 error "$DIR/$tdir/${tfile}2: chmod failed"
2831
2832         # chown should work
2833         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2834                 error "$DIR/$tdir/$tfile: chown failed"
2835         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2836                 error "$DIR/$tdir/${tfile}2: chown failed"
2837
2838         # rename should work
2839         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2840                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2841         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2842                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2843
2844         #remove foreign file
2845         rm $DIR/$tdir/${tfile}.new ||
2846                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2847         rm $DIR/$tdir/${tfile}2.new ||
2848                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2849 }
2850 run_test 27J "basic ops on file with foreign LOV"
2851
2852 test_27K() {
2853         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2854                 skip "Need MDS version newer than 2.12.49"
2855
2856         test_mkdir $DIR/$tdir
2857         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2858         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2859
2860         # create foreign dir (raw way)
2861         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2862                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2863
2864         ! $LFS setdirstripe --foreign --flags foo \
2865                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2866                         error "creating $tdir with '--flags foo' should fail"
2867
2868         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2869                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2870                         error "creating $tdir w/ 0xffffffff flags should fail"
2871
2872         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2873                 error "create_foreign_dir FAILED"
2874
2875         # verify foreign dir (raw way)
2876         parse_foreign_dir -d $DIR/$tdir/$tdir |
2877                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2878                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2879         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2880                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2881         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2882                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2883         parse_foreign_dir -d $DIR/$tdir/$tdir |
2884                 grep "lmv_foreign_flags: 55813$" ||
2885                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2886         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2887                 grep "lmv_foreign_value: 0x" |
2888                 sed 's/lmv_foreign_value: 0x//')
2889         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2890                 sed 's/ //g')
2891         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2892
2893         # create foreign dir (lfs + API)
2894         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2895                 $DIR/$tdir/${tdir}2 ||
2896                 error "$DIR/$tdir/${tdir}2: create failed"
2897
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2899                 grep "lfm_magic:.*0x0CD50CD0" ||
2900                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2901         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2902         # - sizeof(lfm_type) - sizeof(lfm_flags)
2903         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2905         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2907         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2908                 grep "lfm_flags:.*0x0000DA05" ||
2909                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2910         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2911                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2912                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2913
2914         # file create in dir should fail
2915         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2916         touch $DIR/$tdir/${tdir}2/$tfile &&
2917                 error "$DIR/${tdir}2: file create should fail"
2918
2919         # chmod should work
2920         chmod 777 $DIR/$tdir/$tdir ||
2921                 error "$DIR/$tdir: chmod failed"
2922         chmod 777 $DIR/$tdir/${tdir}2 ||
2923                 error "$DIR/${tdir}2: chmod failed"
2924
2925         # chown should work
2926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2927                 error "$DIR/$tdir: chown failed"
2928         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2929                 error "$DIR/${tdir}2: chown failed"
2930
2931         # rename should work
2932         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2933                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2934         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2935                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2936
2937         #remove foreign dir
2938         rmdir $DIR/$tdir/${tdir}.new ||
2939                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2940         rmdir $DIR/$tdir/${tdir}2.new ||
2941                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2942 }
2943 run_test 27K "basic ops on dir with foreign LMV"
2944
2945 test_27L() {
2946         remote_mds_nodsh && skip "remote MDS with nodsh"
2947
2948         local POOL=${POOL:-$TESTNAME}
2949
2950         pool_add $POOL || error "pool_add failed"
2951
2952         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2953                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2954                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2955 }
2956 run_test 27L "lfs pool_list gives correct pool name"
2957
2958 test_27M() {
2959         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2960                 skip "Need MDS version >= than 2.12.57"
2961         remote_mds_nodsh && skip "remote MDS with nodsh"
2962         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2963
2964         test_mkdir $DIR/$tdir
2965
2966         # Set default striping on directory
2967         local setcount=4
2968         local stripe_opt
2969
2970         # if we run against a 2.12 server which lacks overstring support
2971         # then the connect_flag will not report overstriping, even if client
2972         # is 2.14+
2973         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2974                 stripe_opt="-C $setcount"
2975         elif (( $OSTCOUNT >= $setcount )); then
2976                 stripe_opt="-c $setcount"
2977         else
2978                 skip "server does not support overstriping"
2979         fi
2980         $LFS setstripe $stripe_opt $DIR/$tdir
2981
2982         echo 1 > $DIR/$tdir/${tfile}.1
2983         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2984         [ $count -eq $setcount ] ||
2985                 error "(1) stripe count $count, should be $setcount"
2986
2987         # Capture existing append_stripe_count setting for restore
2988         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2989         local mdts=$(comma_list $(mdts_nodes))
2990         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2991
2992         local appendcount=$orig_count
2993         echo 1 >> $DIR/$tdir/${tfile}.2_append
2994         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2995         [ $count -eq $appendcount ] ||
2996                 error "(2)stripe count $count, should be $appendcount for append"
2997
2998         # Disable O_APPEND striping, verify it works
2999         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3000
3001         # Should now get the default striping, which is 4
3002         setcount=4
3003         echo 1 >> $DIR/$tdir/${tfile}.3_append
3004         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3005         [ $count -eq $setcount ] ||
3006                 error "(3) stripe count $count, should be $setcount"
3007
3008         # Try changing the stripe count for append files
3009         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3010
3011         # Append striping is now 2 (directory default is still 4)
3012         appendcount=2
3013         echo 1 >> $DIR/$tdir/${tfile}.4_append
3014         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3015         [ $count -eq $appendcount ] ||
3016                 error "(4) stripe count $count, should be $appendcount for append"
3017
3018         # Test append stripe count of -1
3019         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3020         appendcount=$OSTCOUNT
3021         echo 1 >> $DIR/$tdir/${tfile}.5
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3023         [ $count -eq $appendcount ] ||
3024                 error "(5) stripe count $count, should be $appendcount for append"
3025
3026         # Set append striping back to default of 1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3028
3029         # Try a new default striping, PFL + DOM
3030         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3031
3032         # Create normal DOM file, DOM returns stripe count == 0
3033         setcount=0
3034         touch $DIR/$tdir/${tfile}.6
3035         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3036         [ $count -eq $setcount ] ||
3037                 error "(6) stripe count $count, should be $setcount"
3038
3039         # Show
3040         appendcount=1
3041         echo 1 >> $DIR/$tdir/${tfile}.7_append
3042         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3043         [ $count -eq $appendcount ] ||
3044                 error "(7) stripe count $count, should be $appendcount for append"
3045
3046         # Clean up DOM layout
3047         $LFS setstripe -d $DIR/$tdir
3048
3049         save_layout_restore_at_exit $MOUNT
3050         # Now test that append striping works when layout is from root
3051         $LFS setstripe -c 2 $MOUNT
3052         # Make a special directory for this
3053         mkdir $DIR/${tdir}/${tdir}.2
3054
3055         # Verify for normal file
3056         setcount=2
3057         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3058         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3059         [ $count -eq $setcount ] ||
3060                 error "(8) stripe count $count, should be $setcount"
3061
3062         appendcount=1
3063         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3064         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3065         [ $count -eq $appendcount ] ||
3066                 error "(9) stripe count $count, should be $appendcount for append"
3067
3068         # Now test O_APPEND striping with pools
3069         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3070         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3071
3072         # Create the pool
3073         pool_add $TESTNAME || error "pool creation failed"
3074         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3075
3076         echo 1 >> $DIR/$tdir/${tfile}.10_append
3077
3078         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3079         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3080
3081         # Check that count is still correct
3082         appendcount=1
3083         echo 1 >> $DIR/$tdir/${tfile}.11_append
3084         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3085         [ $count -eq $appendcount ] ||
3086                 error "(11) stripe count $count, should be $appendcount for append"
3087
3088         # Disable O_APPEND stripe count, verify pool works separately
3089         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3090
3091         echo 1 >> $DIR/$tdir/${tfile}.12_append
3092
3093         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3094         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3095
3096         # Remove pool setting, verify it's not applied
3097         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3098
3099         echo 1 >> $DIR/$tdir/${tfile}.13_append
3100
3101         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3102         [ "$pool" = "" ] || error "(13) pool found: $pool"
3103 }
3104 run_test 27M "test O_APPEND striping"
3105
3106 test_27N() {
3107         combined_mgs_mds && skip "needs separate MGS/MDT"
3108
3109         pool_add $TESTNAME || error "pool_add failed"
3110         do_facet mgs "$LCTL pool_list $FSNAME" |
3111                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3112                 error "lctl pool_list on MGS failed"
3113 }
3114 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3115
3116 clean_foreign_symlink() {
3117         trap 0
3118         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3119         for i in $DIR/$tdir/* ; do
3120                 $LFS unlink_foreign $i || true
3121         done
3122 }
3123
3124 test_27O() {
3125         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3126                 skip "Need MDS version newer than 2.12.51"
3127
3128         test_mkdir $DIR/$tdir
3129         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3130         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3131
3132         trap clean_foreign_symlink EXIT
3133
3134         # enable foreign_symlink behaviour
3135         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3136
3137         # foreign symlink LOV format is a partial path by default
3138
3139         # create foreign file (lfs + API)
3140         $LFS setstripe --foreign=symlink --flags 0xda05 \
3141                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3142                 error "$DIR/$tdir/${tfile}: create failed"
3143
3144         $LFS getstripe -v $DIR/$tdir/${tfile} |
3145                 grep "lfm_magic:.*0x0BD70BD0" ||
3146                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3147         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3148                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3149         $LFS getstripe -v $DIR/$tdir/${tfile} |
3150                 grep "lfm_flags:.*0x0000DA05" ||
3151                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3152         $LFS getstripe $DIR/$tdir/${tfile} |
3153                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3155
3156         # modify striping should fail
3157         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3158                 error "$DIR/$tdir/$tfile: setstripe should fail"
3159
3160         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3161         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3162         cat /etc/passwd > $DIR/$tdir/$tfile &&
3163                 error "$DIR/$tdir/$tfile: write should fail"
3164
3165         # rename should succeed
3166         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3167                 error "$DIR/$tdir/$tfile: rename has failed"
3168
3169         #remove foreign_symlink file should fail
3170         rm $DIR/$tdir/${tfile}.new &&
3171                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3172
3173         #test fake symlink
3174         mkdir /tmp/${uuid1} ||
3175                 error "/tmp/${uuid1}: mkdir has failed"
3176         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3177                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3178         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3179         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3180                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3181         #read should succeed now
3182         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3183                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3184         #write should succeed now
3185         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3187         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3188                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3189         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3190                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3191
3192         #check that getstripe still works
3193         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3195
3196         # chmod should still succeed
3197         chmod 644 $DIR/$tdir/${tfile}.new ||
3198                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3199
3200         # chown should still succeed
3201         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3203
3204         # rename should still succeed
3205         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3206                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3207
3208         #remove foreign_symlink file should still fail
3209         rm $DIR/$tdir/${tfile} &&
3210                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3211
3212         #use special ioctl() to unlink foreign_symlink file
3213         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3214                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3215
3216 }
3217 run_test 27O "basic ops on foreign file of symlink type"
3218
3219 test_27P() {
3220         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3221                 skip "Need MDS version newer than 2.12.49"
3222
3223         test_mkdir $DIR/$tdir
3224         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3225         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3226
3227         trap clean_foreign_symlink EXIT
3228
3229         # enable foreign_symlink behaviour
3230         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3231
3232         # foreign symlink LMV format is a partial path by default
3233
3234         # create foreign dir (lfs + API)
3235         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3236                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3237                 error "$DIR/$tdir/${tdir}: create failed"
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_27S() {
3377         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3378                 skip "Need MDS version at least 2.14.54"
3379         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3380                 skip "needs different host for mdt1 ost1"
3381
3382         local count=$(precreated_ost_obj_count 0 0)
3383
3384         echo "precreate count $count"
3385         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3386         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3387         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3388         do_facet mds1 $LCTL set_param fail_loc=0x2109
3389         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3390         do_facet ost1 $LCTL set_param fail_loc=0x252
3391         createmany -o $DIR/$tdir/f $count &
3392         pid=$!
3393         echo "precreate count $(precreated_ost_obj_count 0 0)"
3394         do_facet mds1 $LCTL set_param fail_loc=0
3395         do_facet ost1 $LCTL set_param fail_loc=0
3396         wait $pid || error "createmany failed"
3397         echo "precreate count $(precreated_ost_obj_count 0 0)"
3398 }
3399 run_test 27S "don't deactivate OSP on network issue"
3400
3401 test_27T() {
3402         [ $(facet_host client) == $(facet_host ost1) ] &&
3403                 skip "need ost1 and client on different nodes"
3404
3405 #define OBD_FAIL_OSC_NO_GRANT            0x411
3406         $LCTL set_param fail_loc=0x20000411 fail_val=1
3407 #define OBD_FAIL_OST_ENOSPC              0x215
3408         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3409         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3410         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3411                 error "multiop failed"
3412 }
3413 run_test 27T "no eio on close on partial write due to enosp"
3414
3415 # createtest also checks that device nodes are created and
3416 # then visible correctly (#2091)
3417 test_28() { # bug 2091
3418         test_mkdir $DIR/d28
3419         $CREATETEST $DIR/d28/ct || error "createtest failed"
3420 }
3421 run_test 28 "create/mknod/mkdir with bad file types ============"
3422
3423 test_29() {
3424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3425
3426         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3427                 disable_opencache
3428                 stack_trap "restore_opencache"
3429         }
3430
3431         sync; sleep 1; sync # flush out any dirty pages from previous tests
3432         cancel_lru_locks
3433         test_mkdir $DIR/d29
3434         touch $DIR/d29/foo
3435         log 'first d29'
3436         ls -l $DIR/d29
3437
3438         declare -i LOCKCOUNTORIG=0
3439         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3440                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3441         done
3442         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3443
3444         declare -i LOCKUNUSEDCOUNTORIG=0
3445         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3446                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3447         done
3448
3449         log 'second d29'
3450         ls -l $DIR/d29
3451         log 'done'
3452
3453         declare -i LOCKCOUNTCURRENT=0
3454         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3455                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3456         done
3457
3458         declare -i LOCKUNUSEDCOUNTCURRENT=0
3459         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3460                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3461         done
3462
3463         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3464                 $LCTL set_param -n ldlm.dump_namespaces ""
3465                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3466                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3467                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3468                 return 2
3469         fi
3470         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3471                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3472                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3473                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3474                 return 3
3475         fi
3476 }
3477 run_test 29 "IT_GETATTR regression  ============================"
3478
3479 test_30a() { # was test_30
3480         cp $(which ls) $DIR || cp /bin/ls $DIR
3481         $DIR/ls / || error "Can't execute binary from lustre"
3482         rm $DIR/ls
3483 }
3484 run_test 30a "execute binary from Lustre (execve) =============="
3485
3486 test_30b() {
3487         cp `which ls` $DIR || cp /bin/ls $DIR
3488         chmod go+rx $DIR/ls
3489         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3490         rm $DIR/ls
3491 }
3492 run_test 30b "execute binary from Lustre as non-root ==========="
3493
3494 test_30c() { # b=22376
3495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3496
3497         cp $(which ls) $DIR || cp /bin/ls $DIR
3498         chmod a-rw $DIR/ls
3499         cancel_lru_locks mdc
3500         cancel_lru_locks osc
3501         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3502         rm -f $DIR/ls
3503 }
3504 run_test 30c "execute binary from Lustre without read perms ===="
3505
3506 test_30d() {
3507         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3508
3509         for i in {1..10}; do
3510                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3511                 local PID=$!
3512                 sleep 1
3513                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3514                 wait $PID || error "executing dd from Lustre failed"
3515                 rm -f $DIR/$tfile
3516         done
3517
3518         rm -f $DIR/dd
3519 }
3520 run_test 30d "execute binary from Lustre while clear locks"
3521
3522 test_31a() {
3523         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3524         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3525 }
3526 run_test 31a "open-unlink file =================================="
3527
3528 test_31b() {
3529         touch $DIR/f31 || error "touch $DIR/f31 failed"
3530         ln $DIR/f31 $DIR/f31b || error "ln failed"
3531         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3532         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3533 }
3534 run_test 31b "unlink file with multiple links while open ======="
3535
3536 test_31c() {
3537         touch $DIR/f31 || error "touch $DIR/f31 failed"
3538         ln $DIR/f31 $DIR/f31c || error "ln failed"
3539         multiop_bg_pause $DIR/f31 O_uc ||
3540                 error "multiop_bg_pause for $DIR/f31 failed"
3541         MULTIPID=$!
3542         $MULTIOP $DIR/f31c Ouc
3543         kill -USR1 $MULTIPID
3544         wait $MULTIPID
3545 }
3546 run_test 31c "open-unlink file with multiple links ============="
3547
3548 test_31d() {
3549         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3550         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3551 }
3552 run_test 31d "remove of open directory ========================="
3553
3554 test_31e() { # bug 2904
3555         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3556 }
3557 run_test 31e "remove of open non-empty directory ==============="
3558
3559 test_31f() { # bug 4554
3560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3561
3562         set -vx
3563         test_mkdir $DIR/d31f
3564         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3565         cp /etc/hosts $DIR/d31f
3566         ls -l $DIR/d31f
3567         $LFS getstripe $DIR/d31f/hosts
3568         multiop_bg_pause $DIR/d31f D_c || return 1
3569         MULTIPID=$!
3570
3571         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3572         test_mkdir $DIR/d31f
3573         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3574         cp /etc/hosts $DIR/d31f
3575         ls -l $DIR/d31f
3576         $LFS getstripe $DIR/d31f/hosts
3577         multiop_bg_pause $DIR/d31f D_c || return 1
3578         MULTIPID2=$!
3579
3580         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3581         wait $MULTIPID || error "first opendir $MULTIPID failed"
3582
3583         sleep 6
3584
3585         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3586         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3587         set +vx
3588 }
3589 run_test 31f "remove of open directory with open-unlink file ==="
3590
3591 test_31g() {
3592         echo "-- cross directory link --"
3593         test_mkdir -c1 $DIR/${tdir}ga
3594         test_mkdir -c1 $DIR/${tdir}gb
3595         touch $DIR/${tdir}ga/f
3596         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3597         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3598         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3599         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3600         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3601 }
3602 run_test 31g "cross directory link==============="
3603
3604 test_31h() {
3605         echo "-- cross directory link --"
3606         test_mkdir -c1 $DIR/${tdir}
3607         test_mkdir -c1 $DIR/${tdir}/dir
3608         touch $DIR/${tdir}/f
3609         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3610         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3611         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3612         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3613         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3614 }
3615 run_test 31h "cross directory link under child==============="
3616
3617 test_31i() {
3618         echo "-- cross directory link --"
3619         test_mkdir -c1 $DIR/$tdir
3620         test_mkdir -c1 $DIR/$tdir/dir
3621         touch $DIR/$tdir/dir/f
3622         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3623         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3624         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3625         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3626         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3627 }
3628 run_test 31i "cross directory link under parent==============="
3629
3630 test_31j() {
3631         test_mkdir -c1 -p $DIR/$tdir
3632         test_mkdir -c1 -p $DIR/$tdir/dir1
3633         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3634         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3635         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3636         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3637         return 0
3638 }
3639 run_test 31j "link for directory==============="
3640
3641 test_31k() {
3642         test_mkdir -c1 -p $DIR/$tdir
3643         touch $DIR/$tdir/s
3644         touch $DIR/$tdir/exist
3645         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3646         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3647         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3648         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3649         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3650         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3651         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3652         return 0
3653 }
3654 run_test 31k "link to file: the same, non-existing, dir==============="
3655
3656 test_31m() {
3657         mkdir $DIR/d31m
3658         touch $DIR/d31m/s
3659         mkdir $DIR/d31m2
3660         touch $DIR/d31m2/exist
3661         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3662         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3663         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3664         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3665         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3666         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3667         return 0
3668 }
3669 run_test 31m "link to file: the same, non-existing, dir==============="
3670
3671 test_31n() {
3672         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3673         nlink=$(stat --format=%h $DIR/$tfile)
3674         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3675         local fd=$(free_fd)
3676         local cmd="exec $fd<$DIR/$tfile"
3677         eval $cmd
3678         cmd="exec $fd<&-"
3679         trap "eval $cmd" EXIT
3680         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3681         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3682         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3683         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3684         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3685         eval $cmd
3686 }
3687 run_test 31n "check link count of unlinked file"
3688
3689 link_one() {
3690         local tempfile=$(mktemp $1_XXXXXX)
3691         mlink $tempfile $1 2> /dev/null &&
3692                 echo "$BASHPID: link $tempfile to $1 succeeded"
3693         munlink $tempfile
3694 }
3695
3696 test_31o() { # LU-2901
3697         test_mkdir $DIR/$tdir
3698         for LOOP in $(seq 100); do
3699                 rm -f $DIR/$tdir/$tfile*
3700                 for THREAD in $(seq 8); do
3701                         link_one $DIR/$tdir/$tfile.$LOOP &
3702                 done
3703                 wait
3704                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3705                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3706                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3707                         break || true
3708         done
3709 }
3710 run_test 31o "duplicate hard links with same filename"
3711
3712 test_31p() {
3713         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3714
3715         test_mkdir $DIR/$tdir
3716         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3717         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3718
3719         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3720                 error "open unlink test1 failed"
3721         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3722                 error "open unlink test2 failed"
3723
3724         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3725                 error "test1 still exists"
3726         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3727                 error "test2 still exists"
3728 }
3729 run_test 31p "remove of open striped directory"
3730
3731 test_31q() {
3732         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3733
3734         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3735         index=$($LFS getdirstripe -i $DIR/$tdir)
3736         [ $index -eq 3 ] || error "first stripe index $index != 3"
3737         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3738         [ $index -eq 1 ] || error "second stripe index $index != 1"
3739
3740         # when "-c <stripe_count>" is set, the number of MDTs specified after
3741         # "-i" should equal to the stripe count
3742         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3743 }
3744 run_test 31q "create striped directory on specific MDTs"
3745
3746 #LU-14949
3747 test_31r() {
3748         touch $DIR/$tfile.target
3749         touch $DIR/$tfile.source
3750
3751         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3752         $LCTL set_param fail_loc=0x1419 fail_val=3
3753         cat $DIR/$tfile.target &
3754         CATPID=$!
3755
3756         # Guarantee open is waiting before we get here
3757         sleep 1
3758         mv $DIR/$tfile.source $DIR/$tfile.target
3759
3760         wait $CATPID
3761         RC=$?
3762         if [[ $RC -ne 0 ]]; then
3763                 error "open with cat failed, rc=$RC"
3764         fi
3765 }
3766 run_test 31r "open-rename(replace) race"
3767
3768 cleanup_test32_mount() {
3769         local rc=0
3770         trap 0
3771         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3772         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3773         losetup -d $loopdev || true
3774         rm -rf $DIR/$tdir
3775         return $rc
3776 }
3777
3778 test_32a() {
3779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3780
3781         echo "== more mountpoints and symlinks ================="
3782         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3783         trap cleanup_test32_mount EXIT
3784         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3785         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3786                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3787         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3788                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3789         cleanup_test32_mount
3790 }
3791 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3792
3793 test_32b() {
3794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3795
3796         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3797         trap cleanup_test32_mount EXIT
3798         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3799         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3800                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3801         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3802                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3803         cleanup_test32_mount
3804 }
3805 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3806
3807 test_32c() {
3808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3809
3810         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3811         trap cleanup_test32_mount EXIT
3812         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3813         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3814                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3815         test_mkdir -p $DIR/$tdir/d2/test_dir
3816         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3817                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3818         cleanup_test32_mount
3819 }
3820 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3821
3822 test_32d() {
3823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3824
3825         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3826         trap cleanup_test32_mount EXIT
3827         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3828         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3829                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3830         test_mkdir -p $DIR/$tdir/d2/test_dir
3831         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3832                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3833         cleanup_test32_mount
3834 }
3835 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3836
3837 test_32e() {
3838         rm -fr $DIR/$tdir
3839         test_mkdir -p $DIR/$tdir/tmp
3840         local tmp_dir=$DIR/$tdir/tmp
3841         ln -s $DIR/$tdir $tmp_dir/symlink11
3842         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3843         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3844         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3845 }
3846 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3847
3848 test_32f() {
3849         rm -fr $DIR/$tdir
3850         test_mkdir -p $DIR/$tdir/tmp
3851         local tmp_dir=$DIR/$tdir/tmp
3852         ln -s $DIR/$tdir $tmp_dir/symlink11
3853         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3854         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3855         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3856 }
3857 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3858
3859 test_32g() {
3860         local tmp_dir=$DIR/$tdir/tmp
3861         test_mkdir -p $tmp_dir
3862         test_mkdir $DIR/${tdir}2
3863         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3864         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3865         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3866         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3867         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3868         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3869 }
3870 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3871
3872 test_32h() {
3873         rm -fr $DIR/$tdir $DIR/${tdir}2
3874         tmp_dir=$DIR/$tdir/tmp
3875         test_mkdir -p $tmp_dir
3876         test_mkdir $DIR/${tdir}2
3877         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3878         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3879         ls $tmp_dir/symlink12 || error "listing symlink12"
3880         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3881 }
3882 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3883
3884 test_32i() {
3885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3886
3887         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3888         trap cleanup_test32_mount EXIT
3889         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3890         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3891                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3892         touch $DIR/$tdir/test_file
3893         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3894                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3895         cleanup_test32_mount
3896 }
3897 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3898
3899 test_32j() {
3900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3901
3902         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3903         trap cleanup_test32_mount EXIT
3904         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3905         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3906                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3907         touch $DIR/$tdir/test_file
3908         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3909                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3910         cleanup_test32_mount
3911 }
3912 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3913
3914 test_32k() {
3915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3916
3917         rm -fr $DIR/$tdir
3918         trap cleanup_test32_mount EXIT
3919         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3920         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3921                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3922         test_mkdir -p $DIR/$tdir/d2
3923         touch $DIR/$tdir/d2/test_file || error "touch failed"
3924         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3925                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3926         cleanup_test32_mount
3927 }
3928 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3929
3930 test_32l() {
3931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3932
3933         rm -fr $DIR/$tdir
3934         trap cleanup_test32_mount EXIT
3935         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3936         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3937                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3938         test_mkdir -p $DIR/$tdir/d2
3939         touch $DIR/$tdir/d2/test_file || error "touch failed"
3940         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3941                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3942         cleanup_test32_mount
3943 }
3944 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3945
3946 test_32m() {
3947         rm -fr $DIR/d32m
3948         test_mkdir -p $DIR/d32m/tmp
3949         TMP_DIR=$DIR/d32m/tmp
3950         ln -s $DIR $TMP_DIR/symlink11
3951         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3952         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3953                 error "symlink11 not a link"
3954         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3955                 error "symlink01 not a link"
3956 }
3957 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3958
3959 test_32n() {
3960         rm -fr $DIR/d32n
3961         test_mkdir -p $DIR/d32n/tmp
3962         TMP_DIR=$DIR/d32n/tmp
3963         ln -s $DIR $TMP_DIR/symlink11
3964         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3965         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3966         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3967 }
3968 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3969
3970 test_32o() {
3971         touch $DIR/$tfile
3972         test_mkdir -p $DIR/d32o/tmp
3973         TMP_DIR=$DIR/d32o/tmp
3974         ln -s $DIR/$tfile $TMP_DIR/symlink12
3975         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3976         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3977                 error "symlink12 not a link"
3978         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3979         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3980                 error "$DIR/d32o/tmp/symlink12 not file type"
3981         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3982                 error "$DIR/d32o/symlink02 not file type"
3983 }
3984 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3985
3986 test_32p() {
3987         log 32p_1
3988         rm -fr $DIR/d32p
3989         log 32p_2
3990         rm -f $DIR/$tfile
3991         log 32p_3
3992         touch $DIR/$tfile
3993         log 32p_4
3994         test_mkdir -p $DIR/d32p/tmp
3995         log 32p_5
3996         TMP_DIR=$DIR/d32p/tmp
3997         log 32p_6
3998         ln -s $DIR/$tfile $TMP_DIR/symlink12
3999         log 32p_7
4000         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4001         log 32p_8
4002         cat $DIR/d32p/tmp/symlink12 ||
4003                 error "Can't open $DIR/d32p/tmp/symlink12"
4004         log 32p_9
4005         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4006         log 32p_10
4007 }
4008 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4009
4010 test_32q() {
4011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4012
4013         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4014         trap cleanup_test32_mount EXIT
4015         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4016         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4017         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4018                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4019         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4020         cleanup_test32_mount
4021 }
4022 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4023
4024 test_32r() {
4025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4026
4027         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4028         trap cleanup_test32_mount EXIT
4029         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4030         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4031         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4032                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4033         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4034         cleanup_test32_mount
4035 }
4036 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4037
4038 test_33aa() {
4039         rm -f $DIR/$tfile
4040         touch $DIR/$tfile
4041         chmod 444 $DIR/$tfile
4042         chown $RUNAS_ID $DIR/$tfile
4043         log 33_1
4044         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4045         log 33_2
4046 }
4047 run_test 33aa "write file with mode 444 (should return error)"
4048
4049 test_33a() {
4050         rm -fr $DIR/$tdir
4051         test_mkdir $DIR/$tdir
4052         chown $RUNAS_ID $DIR/$tdir
4053         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4054                 error "$RUNAS create $tdir/$tfile failed"
4055         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4056                 error "open RDWR" || true
4057 }
4058 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4059
4060 test_33b() {
4061         rm -fr $DIR/$tdir
4062         test_mkdir $DIR/$tdir
4063         chown $RUNAS_ID $DIR/$tdir
4064         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4065 }
4066 run_test 33b "test open file with malformed flags (No panic)"
4067
4068 test_33c() {
4069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4070         remote_ost_nodsh && skip "remote OST with nodsh"
4071
4072         local ostnum
4073         local ostname
4074         local write_bytes
4075         local all_zeros
4076
4077         all_zeros=true
4078         test_mkdir $DIR/$tdir
4079         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4080
4081         sync
4082         for ostnum in $(seq $OSTCOUNT); do
4083                 # test-framework's OST numbering is one-based, while Lustre's
4084                 # is zero-based
4085                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4086                 # check if at least some write_bytes stats are counted
4087                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4088                               obdfilter.$ostname.stats |
4089                               awk '/^write_bytes/ {print $7}' )
4090                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4091                 if (( ${write_bytes:-0} > 0 )); then
4092                         all_zeros=false
4093                         break
4094                 fi
4095         done
4096
4097         $all_zeros || return 0
4098
4099         # Write four bytes
4100         echo foo > $DIR/$tdir/bar
4101         # Really write them
4102         sync
4103
4104         # Total up write_bytes after writing.  We'd better find non-zeros.
4105         for ostnum in $(seq $OSTCOUNT); do
4106                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4107                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4108                               obdfilter/$ostname/stats |
4109                               awk '/^write_bytes/ {print $7}' )
4110                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4111                 if (( ${write_bytes:-0} > 0 )); then
4112                         all_zeros=false
4113                         break
4114                 fi
4115         done
4116
4117         if $all_zeros; then
4118                 for ostnum in $(seq $OSTCOUNT); do
4119                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4120                         echo "Check write_bytes is in obdfilter.*.stats:"
4121                         do_facet ost$ostnum lctl get_param -n \
4122                                 obdfilter.$ostname.stats
4123                 done
4124                 error "OST not keeping write_bytes stats (b=22312)"
4125         fi
4126 }
4127 run_test 33c "test write_bytes stats"
4128
4129 test_33d() {
4130         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4132
4133         local MDTIDX=1
4134         local remote_dir=$DIR/$tdir/remote_dir
4135
4136         test_mkdir $DIR/$tdir
4137         $LFS mkdir -i $MDTIDX $remote_dir ||
4138                 error "create remote directory failed"
4139
4140         touch $remote_dir/$tfile
4141         chmod 444 $remote_dir/$tfile
4142         chown $RUNAS_ID $remote_dir/$tfile
4143
4144         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4145
4146         chown $RUNAS_ID $remote_dir
4147         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4148                                         error "create" || true
4149         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4150                                     error "open RDWR" || true
4151         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4152 }
4153 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4154
4155 test_33e() {
4156         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4157
4158         mkdir $DIR/$tdir
4159
4160         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4161         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4162         mkdir $DIR/$tdir/local_dir
4163
4164         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4165         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4166         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4167
4168         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4169                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4170
4171         rmdir $DIR/$tdir/* || error "rmdir failed"
4172
4173         umask 777
4174         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4175         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4176         mkdir $DIR/$tdir/local_dir
4177
4178         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4179         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4180         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4181
4182         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4183                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4184
4185         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4186
4187         umask 000
4188         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4189         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4190         mkdir $DIR/$tdir/local_dir
4191
4192         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4193         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4194         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4195
4196         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4197                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4198 }
4199 run_test 33e "mkdir and striped directory should have same mode"
4200
4201 cleanup_33f() {
4202         trap 0
4203         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4204 }
4205
4206 test_33f() {
4207         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4208         remote_mds_nodsh && skip "remote MDS with nodsh"
4209
4210         mkdir $DIR/$tdir
4211         chmod go+rwx $DIR/$tdir
4212         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4213         trap cleanup_33f EXIT
4214
4215         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4216                 error "cannot create striped directory"
4217
4218         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4219                 error "cannot create files in striped directory"
4220
4221         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4222                 error "cannot remove files in striped directory"
4223
4224         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4225                 error "cannot remove striped directory"
4226
4227         cleanup_33f
4228 }
4229 run_test 33f "nonroot user can create, access, and remove a striped directory"
4230
4231 test_33g() {
4232         mkdir -p $DIR/$tdir/dir2
4233
4234         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4235         echo $err
4236         [[ $err =~ "exists" ]] || error "Not exists error"
4237 }
4238 run_test 33g "nonroot user create already existing root created file"
4239
4240 test_33h() {
4241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4242         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4243                 skip "Need MDS version at least 2.13.50"
4244
4245         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4246                 error "mkdir $tdir failed"
4247         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4248
4249         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4250         local index2
4251
4252         for fname in $DIR/$tdir/$tfile.bak \
4253                      $DIR/$tdir/$tfile.SAV \
4254                      $DIR/$tdir/$tfile.orig \
4255                      $DIR/$tdir/$tfile~; do
4256                 touch $fname  || error "touch $fname failed"
4257                 index2=$($LFS getstripe -m $fname)
4258                 [ $index -eq $index2 ] ||
4259                         error "$fname MDT index mismatch $index != $index2"
4260         done
4261
4262         local failed=0
4263         for i in {1..250}; do
4264                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4265                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4266                         touch $fname  || error "touch $fname failed"
4267                         index2=$($LFS getstripe -m $fname)
4268                         if [[ $index != $index2 ]]; then
4269                                 failed=$((failed + 1))
4270                                 echo "$fname MDT index mismatch $index != $index2"
4271                         fi
4272                 done
4273         done
4274         echo "$failed MDT index mismatches"
4275         (( failed < 20 )) || error "MDT index mismatch $failed times"
4276
4277 }
4278 run_test 33h "temp file is located on the same MDT as target"
4279
4280 test_33i()
4281 {
4282         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4283
4284         local FNAME=$(str_repeat 'f' 250)
4285
4286         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4287         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4288
4289         local count
4290         local total
4291
4292         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4293
4294         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4295
4296         lctl --device %$MDC deactivate
4297         stack_trap "lctl --device %$MDC activate"
4298         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4299         total=$(\ls -l $DIR/$tdir | wc -l)
4300         # "ls -l" will list total in the first line
4301         total=$((total - 1))
4302         (( total + count == 1000 )) ||
4303                 error "ls list $total files, $count files on MDT1"
4304 }
4305 run_test 33i "striped directory can be accessed when one MDT is down"
4306
4307 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4308 test_34a() {
4309         rm -f $DIR/f34
4310         $MCREATE $DIR/f34 || error "mcreate failed"
4311         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4312                 error "getstripe failed"
4313         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4314         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4315                 error "getstripe failed"
4316         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4317                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4318 }
4319 run_test 34a "truncate file that has not been opened ==========="
4320
4321 test_34b() {
4322         [ ! -f $DIR/f34 ] && test_34a
4323         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4324                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4325         $OPENFILE -f O_RDONLY $DIR/f34
4326         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4327                 error "getstripe failed"
4328         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4329                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4330 }
4331 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4332
4333 test_34c() {
4334         [ ! -f $DIR/f34 ] && test_34a
4335         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4336                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4337         $OPENFILE -f O_RDWR $DIR/f34
4338         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4339                 error "$LFS getstripe failed"
4340         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4341                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4342 }
4343 run_test 34c "O_RDWR opening file-with-size works =============="
4344
4345 test_34d() {
4346         [ ! -f $DIR/f34 ] && test_34a
4347         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4348                 error "dd failed"
4349         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4350                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4351         rm $DIR/f34
4352 }
4353 run_test 34d "write to sparse file ============================="
4354
4355 test_34e() {
4356         rm -f $DIR/f34e
4357         $MCREATE $DIR/f34e || error "mcreate failed"
4358         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4359         $CHECKSTAT -s 1000 $DIR/f34e ||
4360                 error "Size of $DIR/f34e not equal to 1000 bytes"
4361         $OPENFILE -f O_RDWR $DIR/f34e
4362         $CHECKSTAT -s 1000 $DIR/f34e ||
4363                 error "Size of $DIR/f34e not equal to 1000 bytes"
4364 }
4365 run_test 34e "create objects, some with size and some without =="
4366
4367 test_34f() { # bug 6242, 6243
4368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4369
4370         SIZE34F=48000
4371         rm -f $DIR/f34f
4372         $MCREATE $DIR/f34f || error "mcreate failed"
4373         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4374         dd if=$DIR/f34f of=$TMP/f34f
4375         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4376         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4377         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4378         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4379         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4380 }
4381 run_test 34f "read from a file with no objects until EOF ======="
4382
4383 test_34g() {
4384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4385
4386         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4387                 error "dd failed"
4388         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4389         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4390                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4391         cancel_lru_locks osc
4392         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4393                 error "wrong size after lock cancel"
4394
4395         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4396         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4397                 error "expanding truncate failed"
4398         cancel_lru_locks osc
4399         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4400                 error "wrong expanded size after lock cancel"
4401 }
4402 run_test 34g "truncate long file ==============================="
4403
4404 test_34h() {
4405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4406
4407         local gid=10
4408         local sz=1000
4409
4410         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4411         sync # Flush the cache so that multiop below does not block on cache
4412              # flush when getting the group lock
4413         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4414         MULTIPID=$!
4415
4416         # Since just timed wait is not good enough, let's do a sync write
4417         # that way we are sure enough time for a roundtrip + processing
4418         # passed + 2 seconds of extra margin.
4419         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4420         rm $DIR/${tfile}-1
4421         sleep 2
4422
4423         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4424                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4425                 kill -9 $MULTIPID
4426         fi
4427         wait $MULTIPID
4428         local nsz=`stat -c %s $DIR/$tfile`
4429         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4430 }
4431 run_test 34h "ftruncate file under grouplock should not block"
4432
4433 test_35a() {
4434         cp /bin/sh $DIR/f35a
4435         chmod 444 $DIR/f35a
4436         chown $RUNAS_ID $DIR/f35a
4437         $RUNAS $DIR/f35a && error || true
4438         rm $DIR/f35a
4439 }
4440 run_test 35a "exec file with mode 444 (should return and not leak)"
4441
4442 test_36a() {
4443         rm -f $DIR/f36
4444         utime $DIR/f36 || error "utime failed for MDS"
4445 }
4446 run_test 36a "MDS utime check (mknod, utime)"
4447
4448 test_36b() {
4449         echo "" > $DIR/f36
4450         utime $DIR/f36 || error "utime failed for OST"
4451 }
4452 run_test 36b "OST utime check (open, utime)"
4453
4454 test_36c() {
4455         rm -f $DIR/d36/f36
4456         test_mkdir $DIR/d36
4457         chown $RUNAS_ID $DIR/d36
4458         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4459 }
4460 run_test 36c "non-root MDS utime check (mknod, utime)"
4461
4462 test_36d() {
4463         [ ! -d $DIR/d36 ] && test_36c
4464         echo "" > $DIR/d36/f36
4465         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4466 }
4467 run_test 36d "non-root OST utime check (open, utime)"
4468
4469 test_36e() {
4470         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4471
4472         test_mkdir $DIR/$tdir
4473         touch $DIR/$tdir/$tfile
4474         $RUNAS utime $DIR/$tdir/$tfile &&
4475                 error "utime worked, expected failure" || true
4476 }
4477 run_test 36e "utime on non-owned file (should return error)"
4478
4479 subr_36fh() {
4480         local fl="$1"
4481         local LANG_SAVE=$LANG
4482         local LC_LANG_SAVE=$LC_LANG
4483         export LANG=C LC_LANG=C # for date language
4484
4485         DATESTR="Dec 20  2000"
4486         test_mkdir $DIR/$tdir
4487         lctl set_param fail_loc=$fl
4488         date; date +%s
4489         cp /etc/hosts $DIR/$tdir/$tfile
4490         sync & # write RPC generated with "current" inode timestamp, but delayed
4491         sleep 1
4492         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4493         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4494         cancel_lru_locks $OSC
4495         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4496         date; date +%s
4497         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4498                 echo "BEFORE: $LS_BEFORE" && \
4499                 echo "AFTER : $LS_AFTER" && \
4500                 echo "WANT  : $DATESTR" && \
4501                 error "$DIR/$tdir/$tfile timestamps changed" || true
4502
4503         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4504 }
4505
4506 test_36f() {
4507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4508
4509         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4510         subr_36fh "0x80000214"
4511 }
4512 run_test 36f "utime on file racing with OST BRW write =========="
4513
4514 test_36g() {
4515         remote_ost_nodsh && skip "remote OST with nodsh"
4516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4517         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4518                 skip "Need MDS version at least 2.12.51"
4519
4520         local fmd_max_age
4521         local fmd
4522         local facet="ost1"
4523         local tgt="obdfilter"
4524
4525         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4526
4527         test_mkdir $DIR/$tdir
4528         fmd_max_age=$(do_facet $facet \
4529                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4530                 head -n 1")
4531
4532         echo "FMD max age: ${fmd_max_age}s"
4533         touch $DIR/$tdir/$tfile
4534         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4535                 gawk '{cnt=cnt+$1}  END{print cnt}')
4536         echo "FMD before: $fmd"
4537         [[ $fmd == 0 ]] &&
4538                 error "FMD wasn't create by touch"
4539         sleep $((fmd_max_age + 12))
4540         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4541                 gawk '{cnt=cnt+$1}  END{print cnt}')
4542         echo "FMD after: $fmd"
4543         [[ $fmd == 0 ]] ||
4544                 error "FMD wasn't expired by ping"
4545 }
4546 run_test 36g "FMD cache expiry ====================="
4547
4548 test_36h() {
4549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4550
4551         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4552         subr_36fh "0x80000227"
4553 }
4554 run_test 36h "utime on file racing with OST BRW write =========="
4555
4556 test_36i() {
4557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4558
4559         test_mkdir $DIR/$tdir
4560         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4561
4562         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4563         local new_mtime=$((mtime + 200))
4564
4565         #change Modify time of striped dir
4566         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4567                         error "change mtime failed"
4568
4569         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4570
4571         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4572 }
4573 run_test 36i "change mtime on striped directory"
4574
4575 # test_37 - duplicate with tests 32q 32r
4576
4577 test_38() {
4578         local file=$DIR/$tfile
4579         touch $file
4580         openfile -f O_DIRECTORY $file
4581         local RC=$?
4582         local ENOTDIR=20
4583         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4584         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4585 }
4586 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4587
4588 test_39a() { # was test_39
4589         touch $DIR/$tfile
4590         touch $DIR/${tfile}2
4591 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4592 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4593 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4594         sleep 2
4595         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4596         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4597                 echo "mtime"
4598                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4599                 echo "atime"
4600                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4601                 echo "ctime"
4602                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4603                 error "O_TRUNC didn't change timestamps"
4604         fi
4605 }
4606 run_test 39a "mtime changed on create"
4607
4608 test_39b() {
4609         test_mkdir -c1 $DIR/$tdir
4610         cp -p /etc/passwd $DIR/$tdir/fopen
4611         cp -p /etc/passwd $DIR/$tdir/flink
4612         cp -p /etc/passwd $DIR/$tdir/funlink
4613         cp -p /etc/passwd $DIR/$tdir/frename
4614         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4615
4616         sleep 1
4617         echo "aaaaaa" >> $DIR/$tdir/fopen
4618         echo "aaaaaa" >> $DIR/$tdir/flink
4619         echo "aaaaaa" >> $DIR/$tdir/funlink
4620         echo "aaaaaa" >> $DIR/$tdir/frename
4621
4622         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4623         local link_new=`stat -c %Y $DIR/$tdir/flink`
4624         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4625         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4626
4627         cat $DIR/$tdir/fopen > /dev/null
4628         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4629         rm -f $DIR/$tdir/funlink2
4630         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4631
4632         for (( i=0; i < 2; i++ )) ; do
4633                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4634                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4635                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4636                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4637
4638                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4639                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4640                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4641                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4642
4643                 cancel_lru_locks $OSC
4644                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4645         done
4646 }
4647 run_test 39b "mtime change on open, link, unlink, rename  ======"
4648
4649 # this should be set to past
4650 TEST_39_MTIME=`date -d "1 year ago" +%s`
4651
4652 # bug 11063
4653 test_39c() {
4654         touch $DIR1/$tfile
4655         sleep 2
4656         local mtime0=`stat -c %Y $DIR1/$tfile`
4657
4658         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4659         local mtime1=`stat -c %Y $DIR1/$tfile`
4660         [ "$mtime1" = $TEST_39_MTIME ] || \
4661                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4662
4663         local d1=`date +%s`
4664         echo hello >> $DIR1/$tfile
4665         local d2=`date +%s`
4666         local mtime2=`stat -c %Y $DIR1/$tfile`
4667         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4668                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4669
4670         mv $DIR1/$tfile $DIR1/$tfile-1
4671
4672         for (( i=0; i < 2; i++ )) ; do
4673                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4674                 [ "$mtime2" = "$mtime3" ] || \
4675                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4676
4677                 cancel_lru_locks $OSC
4678                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4679         done
4680 }
4681 run_test 39c "mtime change on rename ==========================="
4682
4683 # bug 21114
4684 test_39d() {
4685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4686
4687         touch $DIR1/$tfile
4688         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4689
4690         for (( i=0; i < 2; i++ )) ; do
4691                 local mtime=`stat -c %Y $DIR1/$tfile`
4692                 [ $mtime = $TEST_39_MTIME ] || \
4693                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4694
4695                 cancel_lru_locks $OSC
4696                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4697         done
4698 }
4699 run_test 39d "create, utime, stat =============================="
4700
4701 # bug 21114
4702 test_39e() {
4703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4704
4705         touch $DIR1/$tfile
4706         local mtime1=`stat -c %Y $DIR1/$tfile`
4707
4708         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4709
4710         for (( i=0; i < 2; i++ )) ; do
4711                 local mtime2=`stat -c %Y $DIR1/$tfile`
4712                 [ $mtime2 = $TEST_39_MTIME ] || \
4713                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4714
4715                 cancel_lru_locks $OSC
4716                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4717         done
4718 }
4719 run_test 39e "create, stat, utime, stat ========================"
4720
4721 # bug 21114
4722 test_39f() {
4723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4724
4725         touch $DIR1/$tfile
4726         mtime1=`stat -c %Y $DIR1/$tfile`
4727
4728         sleep 2
4729         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4730
4731         for (( i=0; i < 2; i++ )) ; do
4732                 local mtime2=`stat -c %Y $DIR1/$tfile`
4733                 [ $mtime2 = $TEST_39_MTIME ] || \
4734                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4735
4736                 cancel_lru_locks $OSC
4737                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4738         done
4739 }
4740 run_test 39f "create, stat, sleep, utime, stat ================="
4741
4742 # bug 11063
4743 test_39g() {
4744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4745
4746         echo hello >> $DIR1/$tfile
4747         local mtime1=`stat -c %Y $DIR1/$tfile`
4748
4749         sleep 2
4750         chmod o+r $DIR1/$tfile
4751
4752         for (( i=0; i < 2; i++ )) ; do
4753                 local mtime2=`stat -c %Y $DIR1/$tfile`
4754                 [ "$mtime1" = "$mtime2" ] || \
4755                         error "lost mtime: $mtime2, should be $mtime1"
4756
4757                 cancel_lru_locks $OSC
4758                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4759         done
4760 }
4761 run_test 39g "write, chmod, stat ==============================="
4762
4763 # bug 11063
4764 test_39h() {
4765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4766
4767         touch $DIR1/$tfile
4768         sleep 1
4769
4770         local d1=`date`
4771         echo hello >> $DIR1/$tfile
4772         local mtime1=`stat -c %Y $DIR1/$tfile`
4773
4774         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4775         local d2=`date`
4776         if [ "$d1" != "$d2" ]; then
4777                 echo "write and touch not within one second"
4778         else
4779                 for (( i=0; i < 2; i++ )) ; do
4780                         local mtime2=`stat -c %Y $DIR1/$tfile`
4781                         [ "$mtime2" = $TEST_39_MTIME ] || \
4782                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4783
4784                         cancel_lru_locks $OSC
4785                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4786                 done
4787         fi
4788 }
4789 run_test 39h "write, utime within one second, stat ============="
4790
4791 test_39i() {
4792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4793
4794         touch $DIR1/$tfile
4795         sleep 1
4796
4797         echo hello >> $DIR1/$tfile
4798         local mtime1=`stat -c %Y $DIR1/$tfile`
4799
4800         mv $DIR1/$tfile $DIR1/$tfile-1
4801
4802         for (( i=0; i < 2; i++ )) ; do
4803                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4804
4805                 [ "$mtime1" = "$mtime2" ] || \
4806                         error "lost mtime: $mtime2, should be $mtime1"
4807
4808                 cancel_lru_locks $OSC
4809                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4810         done
4811 }
4812 run_test 39i "write, rename, stat =============================="
4813
4814 test_39j() {
4815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4816
4817         start_full_debug_logging
4818         touch $DIR1/$tfile
4819         sleep 1
4820
4821         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4822         lctl set_param fail_loc=0x80000412
4823         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4824                 error "multiop failed"
4825         local multipid=$!
4826         local mtime1=`stat -c %Y $DIR1/$tfile`
4827
4828         mv $DIR1/$tfile $DIR1/$tfile-1
4829
4830         kill -USR1 $multipid
4831         wait $multipid || error "multiop close failed"
4832
4833         for (( i=0; i < 2; i++ )) ; do
4834                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4835                 [ "$mtime1" = "$mtime2" ] ||
4836                         error "mtime is lost on close: $mtime2, " \
4837                               "should be $mtime1"
4838
4839                 cancel_lru_locks
4840                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4841         done
4842         lctl set_param fail_loc=0
4843         stop_full_debug_logging
4844 }
4845 run_test 39j "write, rename, close, stat ======================="
4846
4847 test_39k() {
4848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4849
4850         touch $DIR1/$tfile
4851         sleep 1
4852
4853         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4854         local multipid=$!
4855         local mtime1=`stat -c %Y $DIR1/$tfile`
4856
4857         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4858
4859         kill -USR1 $multipid
4860         wait $multipid || error "multiop close failed"
4861
4862         for (( i=0; i < 2; i++ )) ; do
4863                 local mtime2=`stat -c %Y $DIR1/$tfile`
4864
4865                 [ "$mtime2" = $TEST_39_MTIME ] || \
4866                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4867
4868                 cancel_lru_locks
4869                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4870         done
4871 }
4872 run_test 39k "write, utime, close, stat ========================"
4873
4874 # this should be set to future
4875 TEST_39_ATIME=`date -d "1 year" +%s`
4876
4877 test_39l() {
4878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4879         remote_mds_nodsh && skip "remote MDS with nodsh"
4880
4881         local atime_diff=$(do_facet $SINGLEMDS \
4882                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4883         rm -rf $DIR/$tdir
4884         mkdir_on_mdt0 $DIR/$tdir
4885
4886         # test setting directory atime to future
4887         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4888         local atime=$(stat -c %X $DIR/$tdir)
4889         [ "$atime" = $TEST_39_ATIME ] ||
4890                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4891
4892         # test setting directory atime from future to now
4893         local now=$(date +%s)
4894         touch -a -d @$now $DIR/$tdir
4895
4896         atime=$(stat -c %X $DIR/$tdir)
4897         [ "$atime" -eq "$now"  ] ||
4898                 error "atime is not updated from future: $atime, $now"
4899
4900         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4901         sleep 3
4902
4903         # test setting directory atime when now > dir atime + atime_diff
4904         local d1=$(date +%s)
4905         ls $DIR/$tdir
4906         local d2=$(date +%s)
4907         cancel_lru_locks mdc
4908         atime=$(stat -c %X $DIR/$tdir)
4909         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4910                 error "atime is not updated  : $atime, should be $d2"
4911
4912         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4913         sleep 3
4914
4915         # test not setting directory atime when now < dir atime + atime_diff
4916         ls $DIR/$tdir
4917         cancel_lru_locks mdc
4918         atime=$(stat -c %X $DIR/$tdir)
4919         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4920                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4921
4922         do_facet $SINGLEMDS \
4923                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4924 }
4925 run_test 39l "directory atime update ==========================="
4926
4927 test_39m() {
4928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4929
4930         touch $DIR1/$tfile
4931         sleep 2
4932         local far_past_mtime=$(date -d "May 29 1953" +%s)
4933         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4934
4935         touch -m -d @$far_past_mtime $DIR1/$tfile
4936         touch -a -d @$far_past_atime $DIR1/$tfile
4937
4938         for (( i=0; i < 2; i++ )) ; do
4939                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4940                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4941                         error "atime or mtime set incorrectly"
4942
4943                 cancel_lru_locks $OSC
4944                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4945         done
4946 }
4947 run_test 39m "test atime and mtime before 1970"
4948
4949 test_39n() { # LU-3832
4950         remote_mds_nodsh && skip "remote MDS with nodsh"
4951
4952         local atime_diff=$(do_facet $SINGLEMDS \
4953                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4954         local atime0
4955         local atime1
4956         local atime2
4957
4958         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4959
4960         rm -rf $DIR/$tfile
4961         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4962         atime0=$(stat -c %X $DIR/$tfile)
4963
4964         sleep 5
4965         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4966         atime1=$(stat -c %X $DIR/$tfile)
4967
4968         sleep 5
4969         cancel_lru_locks mdc
4970         cancel_lru_locks osc
4971         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4972         atime2=$(stat -c %X $DIR/$tfile)
4973
4974         do_facet $SINGLEMDS \
4975                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4976
4977         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4978         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4979 }
4980 run_test 39n "check that O_NOATIME is honored"
4981
4982 test_39o() {
4983         TESTDIR=$DIR/$tdir/$tfile
4984         [ -e $TESTDIR ] && rm -rf $TESTDIR
4985         mkdir -p $TESTDIR
4986         cd $TESTDIR
4987         links1=2
4988         ls
4989         mkdir a b
4990         ls
4991         links2=$(stat -c %h .)
4992         [ $(($links1 + 2)) != $links2 ] &&
4993                 error "wrong links count $(($links1 + 2)) != $links2"
4994         rmdir b
4995         links3=$(stat -c %h .)
4996         [ $(($links1 + 1)) != $links3 ] &&
4997                 error "wrong links count $links1 != $links3"
4998         return 0
4999 }
5000 run_test 39o "directory cached attributes updated after create"
5001
5002 test_39p() {
5003         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5004
5005         local MDTIDX=1
5006         TESTDIR=$DIR/$tdir/$tdir
5007         [ -e $TESTDIR ] && rm -rf $TESTDIR
5008         test_mkdir -p $TESTDIR
5009         cd $TESTDIR
5010         links1=2
5011         ls
5012         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5013         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5014         ls
5015         links2=$(stat -c %h .)
5016         [ $(($links1 + 2)) != $links2 ] &&
5017                 error "wrong links count $(($links1 + 2)) != $links2"
5018         rmdir remote_dir2
5019         links3=$(stat -c %h .)
5020         [ $(($links1 + 1)) != $links3 ] &&
5021                 error "wrong links count $links1 != $links3"
5022         return 0
5023 }
5024 run_test 39p "remote directory cached attributes updated after create ========"
5025
5026 test_39r() {
5027         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5028                 skip "no atime update on old OST"
5029         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5030                 skip_env "ldiskfs only test"
5031         fi
5032
5033         local saved_adiff
5034         saved_adiff=$(do_facet ost1 \
5035                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5036         stack_trap "do_facet ost1 \
5037                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5038
5039         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5040
5041         $LFS setstripe -i 0 $DIR/$tfile
5042         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5043                 error "can't write initial file"
5044         cancel_lru_locks osc
5045
5046         # exceed atime_diff and access file
5047         sleep 10
5048         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5049                 error "can't udpate atime"
5050
5051         local atime_cli=$(stat -c %X $DIR/$tfile)
5052         echo "client atime: $atime_cli"
5053         # allow atime update to be written to device
5054         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5055         sleep 5
5056
5057         local ostdev=$(ostdevname 1)
5058         local fid=($(lfs getstripe -y $DIR/$tfile |
5059                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5060         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5061         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5062
5063         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5064         local atime_ost=$(do_facet ost1 "$cmd" |&
5065                           awk -F'[: ]' '/atime:/ { print $4 }')
5066         (( atime_cli == atime_ost )) ||
5067                 error "atime on client $atime_cli != ost $atime_ost"
5068 }
5069 run_test 39r "lazy atime update on OST"
5070
5071 test_39q() { # LU-8041
5072         local testdir=$DIR/$tdir
5073         mkdir -p $testdir
5074         multiop_bg_pause $testdir D_c || error "multiop failed"
5075         local multipid=$!
5076         cancel_lru_locks mdc
5077         kill -USR1 $multipid
5078         local atime=$(stat -c %X $testdir)
5079         [ "$atime" -ne 0 ] || error "atime is zero"
5080 }
5081 run_test 39q "close won't zero out atime"
5082
5083 test_40() {
5084         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5085         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5086                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5087         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5088                 error "$tfile is not 4096 bytes in size"
5089 }
5090 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5091
5092 test_41() {
5093         # bug 1553
5094         small_write $DIR/f41 18
5095 }
5096 run_test 41 "test small file write + fstat ====================="
5097
5098 count_ost_writes() {
5099         lctl get_param -n ${OSC}.*.stats |
5100                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5101                         END { printf("%0.0f", writes) }'
5102 }
5103
5104 # decent default
5105 WRITEBACK_SAVE=500
5106 DIRTY_RATIO_SAVE=40
5107 MAX_DIRTY_RATIO=50
5108 BG_DIRTY_RATIO_SAVE=10
5109 MAX_BG_DIRTY_RATIO=25
5110
5111 start_writeback() {
5112         trap 0
5113         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5114         # dirty_ratio, dirty_background_ratio
5115         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5116                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5117                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5118                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5119         else
5120                 # if file not here, we are a 2.4 kernel
5121                 kill -CONT `pidof kupdated`
5122         fi
5123 }
5124
5125 stop_writeback() {
5126         # setup the trap first, so someone cannot exit the test at the
5127         # exact wrong time and mess up a machine
5128         trap start_writeback EXIT
5129         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5130         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5131                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5132                 sysctl -w vm.dirty_writeback_centisecs=0
5133                 sysctl -w vm.dirty_writeback_centisecs=0
5134                 # save and increase /proc/sys/vm/dirty_ratio
5135                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5136                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5137                 # save and increase /proc/sys/vm/dirty_background_ratio
5138                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5139                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5140         else
5141                 # if file not here, we are a 2.4 kernel
5142                 kill -STOP `pidof kupdated`
5143         fi
5144 }
5145
5146 # ensure that all stripes have some grant before we test client-side cache
5147 setup_test42() {
5148         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5149                 dd if=/dev/zero of=$i bs=4k count=1
5150                 rm $i
5151         done
5152 }
5153
5154 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5155 # file truncation, and file removal.
5156 test_42a() {
5157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5158
5159         setup_test42
5160         cancel_lru_locks $OSC
5161         stop_writeback
5162         sync; sleep 1; sync # just to be safe
5163         BEFOREWRITES=`count_ost_writes`
5164         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5165         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5166         AFTERWRITES=`count_ost_writes`
5167         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5168                 error "$BEFOREWRITES < $AFTERWRITES"
5169         start_writeback
5170 }
5171 run_test 42a "ensure that we don't flush on close"
5172
5173 test_42b() {
5174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5175
5176         setup_test42
5177         cancel_lru_locks $OSC
5178         stop_writeback
5179         sync
5180         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5181         BEFOREWRITES=$(count_ost_writes)
5182         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5183         AFTERWRITES=$(count_ost_writes)
5184         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5185                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5186         fi
5187         BEFOREWRITES=$(count_ost_writes)
5188         sync || error "sync: $?"
5189         AFTERWRITES=$(count_ost_writes)
5190         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5191                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5192         fi
5193         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5194         start_writeback
5195         return 0
5196 }
5197 run_test 42b "test destroy of file with cached dirty data ======"
5198
5199 # if these tests just want to test the effect of truncation,
5200 # they have to be very careful.  consider:
5201 # - the first open gets a {0,EOF}PR lock
5202 # - the first write conflicts and gets a {0, count-1}PW
5203 # - the rest of the writes are under {count,EOF}PW
5204 # - the open for truncate tries to match a {0,EOF}PR
5205 #   for the filesize and cancels the PWs.
5206 # any number of fixes (don't get {0,EOF} on open, match
5207 # composite locks, do smarter file size management) fix
5208 # this, but for now we want these tests to verify that
5209 # the cancellation with truncate intent works, so we
5210 # start the file with a full-file pw lock to match against
5211 # until the truncate.
5212 trunc_test() {
5213         test=$1
5214         file=$DIR/$test
5215         offset=$2
5216         cancel_lru_locks $OSC
5217         stop_writeback
5218         # prime the file with 0,EOF PW to match
5219         touch $file
5220         $TRUNCATE $file 0
5221         sync; sync
5222         # now the real test..
5223         dd if=/dev/zero of=$file bs=1024 count=100
5224         BEFOREWRITES=`count_ost_writes`
5225         $TRUNCATE $file $offset
5226         cancel_lru_locks $OSC
5227         AFTERWRITES=`count_ost_writes`
5228         start_writeback
5229 }
5230
5231 test_42c() {
5232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5233
5234         trunc_test 42c 1024
5235         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5236                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5237         rm $file
5238 }
5239 run_test 42c "test partial truncate of file with cached dirty data"
5240
5241 test_42d() {
5242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5243
5244         trunc_test 42d 0
5245         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5246                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5247         rm $file
5248 }
5249 run_test 42d "test complete truncate of file with cached dirty data"
5250
5251 test_42e() { # bug22074
5252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5253
5254         local TDIR=$DIR/${tdir}e
5255         local pages=16 # hardcoded 16 pages, don't change it.
5256         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5257         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5258         local max_dirty_mb
5259         local warmup_files
5260
5261         test_mkdir $DIR/${tdir}e
5262         $LFS setstripe -c 1 $TDIR
5263         createmany -o $TDIR/f $files
5264
5265         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5266
5267         # we assume that with $OSTCOUNT files, at least one of them will
5268         # be allocated on OST0.
5269         warmup_files=$((OSTCOUNT * max_dirty_mb))
5270         createmany -o $TDIR/w $warmup_files
5271
5272         # write a large amount of data into one file and sync, to get good
5273         # avail_grant number from OST.
5274         for ((i=0; i<$warmup_files; i++)); do
5275                 idx=$($LFS getstripe -i $TDIR/w$i)
5276                 [ $idx -ne 0 ] && continue
5277                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5278                 break
5279         done
5280         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5281         sync
5282         $LCTL get_param $proc_osc0/cur_dirty_bytes
5283         $LCTL get_param $proc_osc0/cur_grant_bytes
5284
5285         # create as much dirty pages as we can while not to trigger the actual
5286         # RPCs directly. but depends on the env, VFS may trigger flush during this
5287         # period, hopefully we are good.
5288         for ((i=0; i<$warmup_files; i++)); do
5289                 idx=$($LFS getstripe -i $TDIR/w$i)
5290                 [ $idx -ne 0 ] && continue
5291                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5292         done
5293         $LCTL get_param $proc_osc0/cur_dirty_bytes
5294         $LCTL get_param $proc_osc0/cur_grant_bytes
5295
5296         # perform the real test
5297         $LCTL set_param $proc_osc0/rpc_stats 0
5298         for ((;i<$files; i++)); do
5299                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5300                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5301         done
5302         sync
5303         $LCTL get_param $proc_osc0/rpc_stats
5304
5305         local percent=0
5306         local have_ppr=false
5307         $LCTL get_param $proc_osc0/rpc_stats |
5308                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5309                         # skip lines until we are at the RPC histogram data
5310                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5311                         $have_ppr || continue
5312
5313                         # we only want the percent stat for < 16 pages
5314                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5315
5316                         percent=$((percent + WPCT))
5317                         if [[ $percent -gt 15 ]]; then
5318                                 error "less than 16-pages write RPCs" \
5319                                       "$percent% > 15%"
5320                                 break
5321                         fi
5322                 done
5323         rm -rf $TDIR
5324 }
5325 run_test 42e "verify sub-RPC writes are not done synchronously"
5326
5327 test_43A() { # was test_43
5328         test_mkdir $DIR/$tdir
5329         cp -p /bin/ls $DIR/$tdir/$tfile
5330         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5331         pid=$!
5332         # give multiop a chance to open
5333         sleep 1
5334
5335         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5336         kill -USR1 $pid
5337         # Wait for multiop to exit
5338         wait $pid
5339 }
5340 run_test 43A "execution of file opened for write should return -ETXTBSY"
5341
5342 test_43a() {
5343         test_mkdir $DIR/$tdir
5344         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5345         $DIR/$tdir/sleep 60 &
5346         SLEEP_PID=$!
5347         # Make sure exec of $tdir/sleep wins race with truncate
5348         sleep 1
5349         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5350         kill $SLEEP_PID
5351 }
5352 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5353
5354 test_43b() {
5355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5356
5357         test_mkdir $DIR/$tdir
5358         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5359         $DIR/$tdir/sleep 60 &
5360         SLEEP_PID=$!
5361         # Make sure exec of $tdir/sleep wins race with truncate
5362         sleep 1
5363         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5364         kill $SLEEP_PID
5365 }
5366 run_test 43b "truncate of file being executed should return -ETXTBSY"
5367
5368 test_43c() {
5369         local testdir="$DIR/$tdir"
5370         test_mkdir $testdir
5371         cp $SHELL $testdir/
5372         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5373                 ( cd $testdir && md5sum -c )
5374 }
5375 run_test 43c "md5sum of copy into lustre"
5376
5377 test_44A() { # was test_44
5378         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5379
5380         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5381         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5382 }
5383 run_test 44A "zero length read from a sparse stripe"
5384
5385 test_44a() {
5386         local nstripe=$($LFS getstripe -c -d $DIR)
5387         [ -z "$nstripe" ] && skip "can't get stripe info"
5388         [[ $nstripe -gt $OSTCOUNT ]] &&
5389                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5390
5391         local stride=$($LFS getstripe -S -d $DIR)
5392         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5393                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5394         fi
5395
5396         OFFSETS="0 $((stride/2)) $((stride-1))"
5397         for offset in $OFFSETS; do
5398                 for i in $(seq 0 $((nstripe-1))); do
5399                         local GLOBALOFFSETS=""
5400                         # size in Bytes
5401                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5402                         local myfn=$DIR/d44a-$size
5403                         echo "--------writing $myfn at $size"
5404                         ll_sparseness_write $myfn $size ||
5405                                 error "ll_sparseness_write"
5406                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5407                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5408                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5409
5410                         for j in $(seq 0 $((nstripe-1))); do
5411                                 # size in Bytes
5412                                 size=$((((j + $nstripe )*$stride + $offset)))
5413                                 ll_sparseness_write $myfn $size ||
5414                                         error "ll_sparseness_write"
5415                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5416                         done
5417                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5418                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5419                         rm -f $myfn
5420                 done
5421         done
5422 }
5423 run_test 44a "test sparse pwrite ==============================="
5424
5425 dirty_osc_total() {
5426         tot=0
5427         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5428                 tot=$(($tot + $d))
5429         done
5430         echo $tot
5431 }
5432 do_dirty_record() {
5433         before=`dirty_osc_total`
5434         echo executing "\"$*\""
5435         eval $*
5436         after=`dirty_osc_total`
5437         echo before $before, after $after
5438 }
5439 test_45() {
5440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5441
5442         f="$DIR/f45"
5443         # Obtain grants from OST if it supports it
5444         echo blah > ${f}_grant
5445         stop_writeback
5446         sync
5447         do_dirty_record "echo blah > $f"
5448         [[ $before -eq $after ]] && error "write wasn't cached"
5449         do_dirty_record "> $f"
5450         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5451         do_dirty_record "echo blah > $f"
5452         [[ $before -eq $after ]] && error "write wasn't cached"
5453         do_dirty_record "sync"
5454         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5455         do_dirty_record "echo blah > $f"
5456         [[ $before -eq $after ]] && error "write wasn't cached"
5457         do_dirty_record "cancel_lru_locks osc"
5458         [[ $before -gt $after ]] ||
5459                 error "lock cancellation didn't lower dirty count"
5460         start_writeback
5461 }
5462 run_test 45 "osc io page accounting ============================"
5463
5464 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5465 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5466 # objects offset and an assert hit when an rpc was built with 1023's mapped
5467 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5468 test_46() {
5469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5470
5471         f="$DIR/f46"
5472         stop_writeback
5473         sync
5474         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5475         sync
5476         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5477         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5478         sync
5479         start_writeback
5480 }
5481 run_test 46 "dirtying a previously written page ================"
5482
5483 # test_47 is removed "Device nodes check" is moved to test_28
5484
5485 test_48a() { # bug 2399
5486         [ "$mds1_FSTYPE" = "zfs" ] &&
5487         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5488                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5489
5490         test_mkdir $DIR/$tdir
5491         cd $DIR/$tdir
5492         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5493         test_mkdir $DIR/$tdir
5494         touch foo || error "'touch foo' failed after recreating cwd"
5495         test_mkdir bar
5496         touch .foo || error "'touch .foo' failed after recreating cwd"
5497         test_mkdir .bar
5498         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5499         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5500         cd . || error "'cd .' failed after recreating cwd"
5501         mkdir . && error "'mkdir .' worked after recreating cwd"
5502         rmdir . && error "'rmdir .' worked after recreating cwd"
5503         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5504         cd .. || error "'cd ..' failed after recreating cwd"
5505 }
5506 run_test 48a "Access renamed working dir (should return errors)="
5507
5508 test_48b() { # bug 2399
5509         rm -rf $DIR/$tdir
5510         test_mkdir $DIR/$tdir
5511         cd $DIR/$tdir
5512         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5513         touch foo && error "'touch foo' worked after removing cwd"
5514         mkdir foo && error "'mkdir foo' worked after removing cwd"
5515         touch .foo && error "'touch .foo' worked after removing cwd"
5516         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5517         ls . > /dev/null && error "'ls .' worked after removing cwd"
5518         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5519         mkdir . && error "'mkdir .' worked after removing cwd"
5520         rmdir . && error "'rmdir .' worked after removing cwd"
5521         ln -s . foo && error "'ln -s .' worked after removing cwd"
5522         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5523 }
5524 run_test 48b "Access removed working dir (should return errors)="
5525
5526 test_48c() { # bug 2350
5527         #lctl set_param debug=-1
5528         #set -vx
5529         rm -rf $DIR/$tdir
5530         test_mkdir -p $DIR/$tdir/dir
5531         cd $DIR/$tdir/dir
5532         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5533         $TRACE touch foo && error "touch foo worked after removing cwd"
5534         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5535         touch .foo && error "touch .foo worked after removing cwd"
5536         mkdir .foo && error "mkdir .foo worked after removing cwd"
5537         $TRACE ls . && error "'ls .' worked after removing cwd"
5538         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5539         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5540         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5541         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5542         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5543 }
5544 run_test 48c "Access removed working subdir (should return errors)"
5545
5546 test_48d() { # bug 2350
5547         #lctl set_param debug=-1
5548         #set -vx
5549         rm -rf $DIR/$tdir
5550         test_mkdir -p $DIR/$tdir/dir
5551         cd $DIR/$tdir/dir
5552         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5553         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5554         $TRACE touch foo && error "'touch foo' worked after removing parent"
5555         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5556         touch .foo && error "'touch .foo' worked after removing parent"
5557         mkdir .foo && error "mkdir .foo worked after removing parent"
5558         $TRACE ls . && error "'ls .' worked after removing parent"
5559         $TRACE ls .. && error "'ls ..' worked after removing parent"
5560         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5561         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5562         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5563         true
5564 }
5565 run_test 48d "Access removed parent subdir (should return errors)"
5566
5567 test_48e() { # bug 4134
5568         #lctl set_param debug=-1
5569         #set -vx
5570         rm -rf $DIR/$tdir
5571         test_mkdir -p $DIR/$tdir/dir
5572         cd $DIR/$tdir/dir
5573         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5574         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5575         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5576         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5577         # On a buggy kernel addition of "touch foo" after cd .. will
5578         # produce kernel oops in lookup_hash_it
5579         touch ../foo && error "'cd ..' worked after recreate parent"
5580         cd $DIR
5581         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5582 }
5583 run_test 48e "Access to recreated parent subdir (should return errors)"
5584
5585 test_48f() {
5586         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5587                 skip "need MDS >= 2.13.55"
5588         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5589         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5590                 skip "needs different host for mdt1 mdt2"
5591         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5592
5593         $LFS mkdir -i0 $DIR/$tdir
5594         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5595
5596         for d in sub1 sub2 sub3; do
5597                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5598                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5599                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5600         done
5601
5602         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5603 }
5604 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5605
5606 test_49() { # LU-1030
5607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5608         remote_ost_nodsh && skip "remote OST with nodsh"
5609
5610         # get ost1 size - $FSNAME-OST0000
5611         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5612                 awk '{ print $4 }')
5613         # write 800M at maximum
5614         [[ $ost1_size -lt 2 ]] && ost1_size=2
5615         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5616
5617         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5618         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5619         local dd_pid=$!
5620
5621         # change max_pages_per_rpc while writing the file
5622         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5623         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5624         # loop until dd process exits
5625         while ps ax -opid | grep -wq $dd_pid; do
5626                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5627                 sleep $((RANDOM % 5 + 1))
5628         done
5629         # restore original max_pages_per_rpc
5630         $LCTL set_param $osc1_mppc=$orig_mppc
5631         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5632 }
5633 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5634
5635 test_50() {
5636         # bug 1485
5637         test_mkdir $DIR/$tdir
5638         cd $DIR/$tdir
5639         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5640 }
5641 run_test 50 "special situations: /proc symlinks  ==============="
5642
5643 test_51a() {    # was test_51
5644         # bug 1516 - create an empty entry right after ".." then split dir
5645         test_mkdir -c1 $DIR/$tdir
5646         touch $DIR/$tdir/foo
5647         $MCREATE $DIR/$tdir/bar
5648         rm $DIR/$tdir/foo
5649         createmany -m $DIR/$tdir/longfile 201
5650         FNUM=202
5651         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5652                 $MCREATE $DIR/$tdir/longfile$FNUM
5653                 FNUM=$(($FNUM + 1))
5654                 echo -n "+"
5655         done
5656         echo
5657         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5658 }
5659 run_test 51a "special situations: split htree with empty entry =="
5660
5661 cleanup_print_lfs_df () {
5662         trap 0
5663         $LFS df
5664         $LFS df -i
5665 }
5666
5667 test_51b() {
5668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5669
5670         local dir=$DIR/$tdir
5671         local nrdirs=$((65536 + 100))
5672
5673         # cleanup the directory
5674         rm -fr $dir
5675
5676         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5677
5678         $LFS df
5679         $LFS df -i
5680         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5681         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5682         [[ $numfree -lt $nrdirs ]] &&
5683                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5684
5685         # need to check free space for the directories as well
5686         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5687         numfree=$(( blkfree / $(fs_inode_ksize) ))
5688         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5689
5690         trap cleanup_print_lfs_df EXIT
5691
5692         # create files
5693         createmany -d $dir/d $nrdirs || {
5694                 unlinkmany $dir/d $nrdirs
5695                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5696         }
5697
5698         # really created :
5699         nrdirs=$(ls -U $dir | wc -l)
5700
5701         # unlink all but 100 subdirectories, then check it still works
5702         local left=100
5703         local delete=$((nrdirs - left))
5704
5705         $LFS df
5706         $LFS df -i
5707
5708         # for ldiskfs the nlink count should be 1, but this is OSD specific
5709         # and so this is listed for informational purposes only
5710         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5711         unlinkmany -d $dir/d $delete ||
5712                 error "unlink of first $delete subdirs failed"
5713
5714         echo "nlink between: $(stat -c %h $dir)"
5715         local found=$(ls -U $dir | wc -l)
5716         [ $found -ne $left ] &&
5717                 error "can't find subdirs: found only $found, expected $left"
5718
5719         unlinkmany -d $dir/d $delete $left ||
5720                 error "unlink of second $left subdirs failed"
5721         # regardless of whether the backing filesystem tracks nlink accurately
5722         # or not, the nlink count shouldn't be more than "." and ".." here
5723         local after=$(stat -c %h $dir)
5724         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5725                 echo "nlink after: $after"
5726
5727         cleanup_print_lfs_df
5728 }
5729 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5730
5731 test_51d() {
5732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5733         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5734         local qos_old
5735
5736         test_mkdir $DIR/$tdir
5737         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5738
5739         qos_old=$(do_facet mds1 \
5740                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5741         do_nodes $(comma_list $(mdts_nodes)) \
5742                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5743         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5744                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5745
5746         createmany -o $DIR/$tdir/t- 1000
5747         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5748         for ((n = 0; n < $OSTCOUNT; n++)); do
5749                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5750                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5751                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5752                             '($1 == '$n') { objs += 1 } \
5753                             END { printf("%0.0f", objs) }')
5754                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5755         done
5756         unlinkmany $DIR/$tdir/t- 1000
5757
5758         nlast=0
5759         for ((n = 0; n < $OSTCOUNT; n++)); do
5760                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5761                         { $LFS df && $LFS df -i &&
5762                         error "OST $n has fewer objects vs. OST $nlast" \
5763                               " (${objs[$n]} < ${objs[$nlast]}"; }
5764                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5765                         { $LFS df && $LFS df -i &&
5766                         error "OST $n has fewer objects vs. OST $nlast" \
5767                               " (${objs[$n]} < ${objs[$nlast]}"; }
5768
5769                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5770                         { $LFS df && $LFS df -i &&
5771                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5772                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5773                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5774                         { $LFS df && $LFS df -i &&
5775                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5776                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5777                 nlast=$n
5778         done
5779 }
5780 run_test 51d "check object distribution"
5781
5782 test_51e() {
5783         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5784                 skip_env "ldiskfs only test"
5785         fi
5786
5787         test_mkdir -c1 $DIR/$tdir
5788         test_mkdir -c1 $DIR/$tdir/d0
5789
5790         touch $DIR/$tdir/d0/foo
5791         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5792                 error "file exceed 65000 nlink limit!"
5793         unlinkmany $DIR/$tdir/d0/f- 65001
5794         return 0
5795 }
5796 run_test 51e "check file nlink limit"
5797
5798 test_51f() {
5799         test_mkdir $DIR/$tdir
5800
5801         local max=100000
5802         local ulimit_old=$(ulimit -n)
5803         local spare=20 # number of spare fd's for scripts/libraries, etc.
5804         local mdt=$($LFS getstripe -m $DIR/$tdir)
5805         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5806
5807         echo "MDT$mdt numfree=$numfree, max=$max"
5808         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5809         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5810                 while ! ulimit -n $((numfree + spare)); do
5811                         numfree=$((numfree * 3 / 4))
5812                 done
5813                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5814         else
5815                 echo "left ulimit at $ulimit_old"
5816         fi
5817
5818         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5819                 unlinkmany $DIR/$tdir/f $numfree
5820                 error "create+open $numfree files in $DIR/$tdir failed"
5821         }
5822         ulimit -n $ulimit_old
5823
5824         # if createmany exits at 120s there will be fewer than $numfree files
5825         unlinkmany $DIR/$tdir/f $numfree || true
5826 }
5827 run_test 51f "check many open files limit"
5828
5829 test_52a() {
5830         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5831         test_mkdir $DIR/$tdir
5832         touch $DIR/$tdir/foo
5833         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5834         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5835         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5836         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5837         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5838                                         error "link worked"
5839         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5840         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5841         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5842                                                      error "lsattr"
5843         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5844         cp -r $DIR/$tdir $TMP/
5845         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5846 }
5847 run_test 52a "append-only flag test (should return errors)"
5848
5849 test_52b() {
5850         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5851         test_mkdir $DIR/$tdir
5852         touch $DIR/$tdir/foo
5853         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5854         cat test > $DIR/$tdir/foo && error "cat test worked"
5855         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5856         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5857         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5858                                         error "link worked"
5859         echo foo >> $DIR/$tdir/foo && error "echo worked"
5860         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5861         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5862         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5863         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5864                                                         error "lsattr"
5865         chattr -i $DIR/$tdir/foo || error "chattr failed"
5866
5867         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5868 }
5869 run_test 52b "immutable flag test (should return errors) ======="
5870
5871 test_53() {
5872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5873         remote_mds_nodsh && skip "remote MDS with nodsh"
5874         remote_ost_nodsh && skip "remote OST with nodsh"
5875
5876         local param
5877         local param_seq
5878         local ostname
5879         local mds_last
5880         local mds_last_seq
5881         local ost_last
5882         local ost_last_seq
5883         local ost_last_id
5884         local ostnum
5885         local node
5886         local found=false
5887         local support_last_seq=true
5888
5889         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5890                 support_last_seq=false
5891
5892         # only test MDT0000
5893         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5894         local value
5895         for value in $(do_facet $SINGLEMDS \
5896                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5897                 param=$(echo ${value[0]} | cut -d "=" -f1)
5898                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5899
5900                 if $support_last_seq; then
5901                         param_seq=$(echo $param |
5902                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5903                         mds_last_seq=$(do_facet $SINGLEMDS \
5904                                        $LCTL get_param -n $param_seq)
5905                 fi
5906                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5907
5908                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5909                 node=$(facet_active_host ost$((ostnum+1)))
5910                 param="obdfilter.$ostname.last_id"
5911                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5912                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5913                         ost_last_id=$ost_last
5914
5915                         if $support_last_seq; then
5916                                 ost_last_id=$(echo $ost_last |
5917                                               awk -F':' '{print $2}' |
5918                                               sed -e "s/^0x//g")
5919                                 ost_last_seq=$(echo $ost_last |
5920                                                awk -F':' '{print $1}')
5921                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5922                         fi
5923
5924                         if [[ $ost_last_id != $mds_last ]]; then
5925                                 error "$ost_last_id != $mds_last"
5926                         else
5927                                 found=true
5928                                 break
5929                         fi
5930                 done
5931         done
5932         $found || error "can not match last_seq/last_id for $mdtosc"
5933         return 0
5934 }
5935 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5936
5937 test_54a() {
5938         perl -MSocket -e ';' || skip "no Socket perl module installed"
5939
5940         $SOCKETSERVER $DIR/socket ||
5941                 error "$SOCKETSERVER $DIR/socket failed: $?"
5942         $SOCKETCLIENT $DIR/socket ||
5943                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5944         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5945 }
5946 run_test 54a "unix domain socket test =========================="
5947
5948 test_54b() {
5949         f="$DIR/f54b"
5950         mknod $f c 1 3
5951         chmod 0666 $f
5952         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5953 }
5954 run_test 54b "char device works in lustre ======================"
5955
5956 find_loop_dev() {
5957         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5958         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5959         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5960
5961         for i in $(seq 3 7); do
5962                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5963                 LOOPDEV=$LOOPBASE$i
5964                 LOOPNUM=$i
5965                 break
5966         done
5967 }
5968
5969 cleanup_54c() {
5970         local rc=0
5971         loopdev="$DIR/loop54c"
5972
5973         trap 0
5974         $UMOUNT $DIR/$tdir || rc=$?
5975         losetup -d $loopdev || true
5976         losetup -d $LOOPDEV || true
5977         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5978         return $rc
5979 }
5980
5981 test_54c() {
5982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5983
5984         loopdev="$DIR/loop54c"
5985
5986         find_loop_dev
5987         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5988         trap cleanup_54c EXIT
5989         mknod $loopdev b 7 $LOOPNUM
5990         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5991         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5992         losetup $loopdev $DIR/$tfile ||
5993                 error "can't set up $loopdev for $DIR/$tfile"
5994         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5995         test_mkdir $DIR/$tdir
5996         mount -t ext2 $loopdev $DIR/$tdir ||
5997                 error "error mounting $loopdev on $DIR/$tdir"
5998         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5999                 error "dd write"
6000         df $DIR/$tdir
6001         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6002                 error "dd read"
6003         cleanup_54c
6004 }
6005 run_test 54c "block device works in lustre ====================="
6006
6007 test_54d() {
6008         local pipe="$DIR/$tfile.pipe"
6009         local string="aaaaaa"
6010
6011         mknod $pipe p
6012         echo -n "$string" > $pipe &
6013         local result=$(cat $pipe)
6014         [[ "$result" == "$string" ]] || error "$result != $string"
6015 }
6016 run_test 54d "fifo device works in lustre ======================"
6017
6018 test_54e() {
6019         f="$DIR/f54e"
6020         string="aaaaaa"
6021         cp -aL /dev/console $f
6022         echo $string > $f || error "echo $string to $f failed"
6023 }
6024 run_test 54e "console/tty device works in lustre ======================"
6025
6026 test_56a() {
6027         local numfiles=3
6028         local numdirs=2
6029         local dir=$DIR/$tdir
6030
6031         rm -rf $dir
6032         test_mkdir -p $dir/dir
6033         for i in $(seq $numfiles); do
6034                 touch $dir/file$i
6035                 touch $dir/dir/file$i
6036         done
6037
6038         local numcomp=$($LFS getstripe --component-count $dir)
6039
6040         [[ $numcomp == 0 ]] && numcomp=1
6041
6042         # test lfs getstripe with --recursive
6043         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6044
6045         [[ $filenum -eq $((numfiles * 2)) ]] ||
6046                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6047         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6048         [[ $filenum -eq $numfiles ]] ||
6049                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6050         echo "$LFS getstripe showed obdidx or l_ost_idx"
6051
6052         # test lfs getstripe with file instead of dir
6053         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6054         [[ $filenum -eq 1 ]] ||
6055                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6056         echo "$LFS getstripe file1 passed"
6057
6058         #test lfs getstripe with --verbose
6059         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6060         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6061                 error "$LFS getstripe --verbose $dir: "\
6062                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6063         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6064                 error "$LFS getstripe $dir: showed lmm_magic"
6065
6066         #test lfs getstripe with -v prints lmm_fid
6067         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6068         local countfids=$((numdirs + numfiles * numcomp))
6069         [[ $filenum -eq $countfids ]] ||
6070                 error "$LFS getstripe -v $dir: "\
6071                       "got $filenum want $countfids lmm_fid"
6072         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6073                 error "$LFS getstripe $dir: showed lmm_fid by default"
6074         echo "$LFS getstripe --verbose passed"
6075
6076         #check for FID information
6077         local fid1=$($LFS getstripe --fid $dir/file1)
6078         local fid2=$($LFS getstripe --verbose $dir/file1 |
6079                      awk '/lmm_fid: / { print $2; exit; }')
6080         local fid3=$($LFS path2fid $dir/file1)
6081
6082         [ "$fid1" != "$fid2" ] &&
6083                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6084         [ "$fid1" != "$fid3" ] &&
6085                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6086         echo "$LFS getstripe --fid passed"
6087
6088         #test lfs getstripe with --obd
6089         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6090                 error "$LFS getstripe --obd wrong_uuid: should return error"
6091
6092         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6093
6094         local ostidx=1
6095         local obduuid=$(ostuuid_from_index $ostidx)
6096         local found=$($LFS getstripe -r --obd $obduuid $dir |
6097                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6098
6099         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6100         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6101                 ((filenum--))
6102         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6103                 ((filenum--))
6104
6105         [[ $found -eq $filenum ]] ||
6106                 error "$LFS getstripe --obd: found $found expect $filenum"
6107         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6108                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6109                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6110                 error "$LFS getstripe --obd: should not show file on other obd"
6111         echo "$LFS getstripe --obd passed"
6112 }
6113 run_test 56a "check $LFS getstripe"
6114
6115 test_56b() {
6116         local dir=$DIR/$tdir
6117         local numdirs=3
6118
6119         test_mkdir $dir
6120         for i in $(seq $numdirs); do
6121                 test_mkdir $dir/dir$i
6122         done
6123
6124         # test lfs getdirstripe default mode is non-recursion, which is
6125         # different from lfs getstripe
6126         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6127
6128         [[ $dircnt -eq 1 ]] ||
6129                 error "$LFS getdirstripe: found $dircnt, not 1"
6130         dircnt=$($LFS getdirstripe --recursive $dir |
6131                 grep -c lmv_stripe_count)
6132         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6133                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6134 }
6135 run_test 56b "check $LFS getdirstripe"
6136
6137 test_56c() {
6138         remote_ost_nodsh && skip "remote OST with nodsh"
6139
6140         local ost_idx=0
6141         local ost_name=$(ostname_from_index $ost_idx)
6142         local old_status=$(ost_dev_status $ost_idx)
6143         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6144
6145         [[ -z "$old_status" ]] ||
6146                 skip_env "OST $ost_name is in $old_status status"
6147
6148         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6149         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6150                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6151         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6152                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6153                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6154         fi
6155
6156         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6157                 error "$LFS df -v showing inactive devices"
6158         sleep_maxage
6159
6160         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6161
6162         [[ "$new_status" =~ "D" ]] ||
6163                 error "$ost_name status is '$new_status', missing 'D'"
6164         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6165                 [[ "$new_status" =~ "N" ]] ||
6166                         error "$ost_name status is '$new_status', missing 'N'"
6167         fi
6168         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6169                 [[ "$new_status" =~ "f" ]] ||
6170                         error "$ost_name status is '$new_status', missing 'f'"
6171         fi
6172
6173         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6174         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6175                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6176         [[ -z "$p" ]] && restore_lustre_params < $p || true
6177         sleep_maxage
6178
6179         new_status=$(ost_dev_status $ost_idx)
6180         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6181                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6182         # can't check 'f' as devices may actually be on flash
6183 }
6184 run_test 56c "check 'lfs df' showing device status"
6185
6186 test_56d() {
6187         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6188         local osts=$($LFS df -v $MOUNT | grep -c OST)
6189
6190         $LFS df $MOUNT
6191
6192         (( mdts == MDSCOUNT )) ||
6193                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6194         (( osts == OSTCOUNT )) ||
6195                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6196 }
6197 run_test 56d "'lfs df -v' prints only configured devices"
6198
6199 test_56e() {
6200         err_enoent=2 # No such file or directory
6201         err_eopnotsupp=95 # Operation not supported
6202
6203         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6204         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6205
6206         # Check for handling of path not exists
6207         output=$($LFS df $enoent_mnt 2>&1)
6208         ret=$?
6209
6210         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6211         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6212                 error "expect failure $err_enoent, not $ret"
6213
6214         # Check for handling of non-Lustre FS
6215         output=$($LFS df $notsup_mnt)
6216         ret=$?
6217
6218         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6219         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6220                 error "expect success $err_eopnotsupp, not $ret"
6221
6222         # Check for multiple LustreFS argument
6223         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6224         ret=$?
6225
6226         [[ $output -eq 3 && $ret -eq 0 ]] ||
6227                 error "expect success 3, not $output, rc = $ret"
6228
6229         # Check for correct non-Lustre FS handling among multiple
6230         # LustreFS argument
6231         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6232                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6233         ret=$?
6234
6235         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6236                 error "expect success 2, not $output, rc = $ret"
6237 }
6238 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6239
6240 NUMFILES=3
6241 NUMDIRS=3
6242 setup_56() {
6243         local local_tdir="$1"
6244         local local_numfiles="$2"
6245         local local_numdirs="$3"
6246         local dir_params="$4"
6247         local dir_stripe_params="$5"
6248
6249         if [ ! -d "$local_tdir" ] ; then
6250                 test_mkdir -p $dir_stripe_params $local_tdir
6251                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6252                 for i in $(seq $local_numfiles) ; do
6253                         touch $local_tdir/file$i
6254                 done
6255                 for i in $(seq $local_numdirs) ; do
6256                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6257                         for j in $(seq $local_numfiles) ; do
6258                                 touch $local_tdir/dir$i/file$j
6259                         done
6260                 done
6261         fi
6262 }
6263
6264 setup_56_special() {
6265         local local_tdir=$1
6266         local local_numfiles=$2
6267         local local_numdirs=$3
6268
6269         setup_56 $local_tdir $local_numfiles $local_numdirs
6270
6271         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6272                 for i in $(seq $local_numfiles) ; do
6273                         mknod $local_tdir/loop${i}b b 7 $i
6274                         mknod $local_tdir/null${i}c c 1 3
6275                         ln -s $local_tdir/file1 $local_tdir/link${i}
6276                 done
6277                 for i in $(seq $local_numdirs) ; do
6278                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6279                         mknod $local_tdir/dir$i/null${i}c c 1 3
6280                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6281                 done
6282         fi
6283 }
6284
6285 test_56g() {
6286         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6287         local expected=$(($NUMDIRS + 2))
6288
6289         setup_56 $dir $NUMFILES $NUMDIRS
6290
6291         # test lfs find with -name
6292         for i in $(seq $NUMFILES) ; do
6293                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6294
6295                 [ $nums -eq $expected ] ||
6296                         error "lfs find -name '*$i' $dir wrong: "\
6297                               "found $nums, expected $expected"
6298         done
6299 }
6300 run_test 56g "check lfs find -name"
6301
6302 test_56h() {
6303         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6304         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6305
6306         setup_56 $dir $NUMFILES $NUMDIRS
6307
6308         # test lfs find with ! -name
6309         for i in $(seq $NUMFILES) ; do
6310                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6311
6312                 [ $nums -eq $expected ] ||
6313                         error "lfs find ! -name '*$i' $dir wrong: "\
6314                               "found $nums, expected $expected"
6315         done
6316 }
6317 run_test 56h "check lfs find ! -name"
6318
6319 test_56i() {
6320         local dir=$DIR/$tdir
6321
6322         test_mkdir $dir
6323
6324         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6325         local out=$($cmd)
6326
6327         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6328 }
6329 run_test 56i "check 'lfs find -ost UUID' skips directories"
6330
6331 test_56j() {
6332         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6333
6334         setup_56_special $dir $NUMFILES $NUMDIRS
6335
6336         local expected=$((NUMDIRS + 1))
6337         local cmd="$LFS find -type d $dir"
6338         local nums=$($cmd | wc -l)
6339
6340         [ $nums -eq $expected ] ||
6341                 error "'$cmd' wrong: found $nums, expected $expected"
6342 }
6343 run_test 56j "check lfs find -type d"
6344
6345 test_56k() {
6346         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6347
6348         setup_56_special $dir $NUMFILES $NUMDIRS
6349
6350         local expected=$(((NUMDIRS + 1) * NUMFILES))
6351         local cmd="$LFS find -type f $dir"
6352         local nums=$($cmd | wc -l)
6353
6354         [ $nums -eq $expected ] ||
6355                 error "'$cmd' wrong: found $nums, expected $expected"
6356 }
6357 run_test 56k "check lfs find -type f"
6358
6359 test_56l() {
6360         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6361
6362         setup_56_special $dir $NUMFILES $NUMDIRS
6363
6364         local expected=$((NUMDIRS + NUMFILES))
6365         local cmd="$LFS find -type b $dir"
6366         local nums=$($cmd | wc -l)
6367
6368         [ $nums -eq $expected ] ||
6369                 error "'$cmd' wrong: found $nums, expected $expected"
6370 }
6371 run_test 56l "check lfs find -type b"
6372
6373 test_56m() {
6374         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6375
6376         setup_56_special $dir $NUMFILES $NUMDIRS
6377
6378         local expected=$((NUMDIRS + NUMFILES))
6379         local cmd="$LFS find -type c $dir"
6380         local nums=$($cmd | wc -l)
6381         [ $nums -eq $expected ] ||
6382                 error "'$cmd' wrong: found $nums, expected $expected"
6383 }
6384 run_test 56m "check lfs find -type c"
6385
6386 test_56n() {
6387         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6388         setup_56_special $dir $NUMFILES $NUMDIRS
6389
6390         local expected=$((NUMDIRS + NUMFILES))
6391         local cmd="$LFS find -type l $dir"
6392         local nums=$($cmd | wc -l)
6393
6394         [ $nums -eq $expected ] ||
6395                 error "'$cmd' wrong: found $nums, expected $expected"
6396 }
6397 run_test 56n "check lfs find -type l"
6398
6399 test_56o() {
6400         local dir=$DIR/$tdir
6401
6402         setup_56 $dir $NUMFILES $NUMDIRS
6403         utime $dir/file1 > /dev/null || error "utime (1)"
6404         utime $dir/file2 > /dev/null || error "utime (2)"
6405         utime $dir/dir1 > /dev/null || error "utime (3)"
6406         utime $dir/dir2 > /dev/null || error "utime (4)"
6407         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6408         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6409
6410         local expected=4
6411         local nums=$($LFS find -mtime +0 $dir | wc -l)
6412
6413         [ $nums -eq $expected ] ||
6414                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6415
6416         expected=12
6417         cmd="$LFS find -mtime 0 $dir"
6418         nums=$($cmd | wc -l)
6419         [ $nums -eq $expected ] ||
6420                 error "'$cmd' wrong: found $nums, expected $expected"
6421 }
6422 run_test 56o "check lfs find -mtime for old files"
6423
6424 test_56ob() {
6425         local dir=$DIR/$tdir
6426         local expected=1
6427         local count=0
6428
6429         # just to make sure there is something that won't be found
6430         test_mkdir $dir
6431         touch $dir/$tfile.now
6432
6433         for age in year week day hour min; do
6434                 count=$((count + 1))
6435
6436                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6437                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6438                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6439
6440                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6441                 local nums=$($cmd | wc -l)
6442                 [ $nums -eq $expected ] ||
6443                         error "'$cmd' wrong: found $nums, expected $expected"
6444
6445                 cmd="$LFS find $dir -atime $count${age:0:1}"
6446                 nums=$($cmd | wc -l)
6447                 [ $nums -eq $expected ] ||
6448                         error "'$cmd' wrong: found $nums, expected $expected"
6449         done
6450
6451         sleep 2
6452         cmd="$LFS find $dir -ctime +1s -type f"
6453         nums=$($cmd | wc -l)
6454         (( $nums == $count * 2 + 1)) ||
6455                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6456 }
6457 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6458
6459 test_newerXY_base() {
6460         local x=$1
6461         local y=$2
6462         local dir=$DIR/$tdir
6463         local ref
6464         local negref
6465
6466         if [ $y == "t" ]; then
6467                 if [ $x == "b" ]; then
6468                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6469                 else
6470                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6471                 fi
6472         else
6473                 ref=$DIR/$tfile.newer.$x$y
6474                 touch $ref || error "touch $ref failed"
6475         fi
6476
6477         echo "before = $ref"
6478         sleep 2
6479         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6480         sleep 2
6481         if [ $y == "t" ]; then
6482                 if [ $x == "b" ]; then
6483                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6484                 else
6485                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6486                 fi
6487         else
6488                 negref=$DIR/$tfile.negnewer.$x$y
6489                 touch $negref || error "touch $negref failed"
6490         fi
6491
6492         echo "after = $negref"
6493         local cmd="$LFS find $dir -newer$x$y $ref"
6494         local nums=$(eval $cmd | wc -l)
6495         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6496
6497         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6498                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6499
6500         cmd="$LFS find $dir ! -newer$x$y $negref"
6501         nums=$(eval $cmd | wc -l)
6502         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6503                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6504
6505         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6506         nums=$(eval $cmd | wc -l)
6507         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6508                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6509
6510         rm -rf $DIR/*
6511 }
6512
6513 test_56oc() {
6514         test_newerXY_base "a" "a"
6515         test_newerXY_base "a" "m"
6516         test_newerXY_base "a" "c"
6517         test_newerXY_base "m" "a"
6518         test_newerXY_base "m" "m"
6519         test_newerXY_base "m" "c"
6520         test_newerXY_base "c" "a"
6521         test_newerXY_base "c" "m"
6522         test_newerXY_base "c" "c"
6523
6524         [[ -n "$sles_version" ]] &&
6525                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6526
6527         test_newerXY_base "a" "t"
6528         test_newerXY_base "m" "t"
6529         test_newerXY_base "c" "t"
6530
6531         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6532            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6533                 ! btime_supported && echo "btime unsupported" && return 0
6534
6535         test_newerXY_base "b" "b"
6536         test_newerXY_base "b" "t"
6537 }
6538 run_test 56oc "check lfs find -newerXY work"
6539
6540 btime_supported() {
6541         local dir=$DIR/$tdir
6542         local rc
6543
6544         mkdir -p $dir
6545         touch $dir/$tfile
6546         $LFS find $dir -btime -1d -type f
6547         rc=$?
6548         rm -rf $dir
6549         return $rc
6550 }
6551
6552 test_56od() {
6553         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6554                 ! btime_supported && skip "btime unsupported on MDS"
6555
6556         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6557                 ! btime_supported && skip "btime unsupported on clients"
6558
6559         local dir=$DIR/$tdir
6560         local ref=$DIR/$tfile.ref
6561         local negref=$DIR/$tfile.negref
6562
6563         mkdir $dir || error "mkdir $dir failed"
6564         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6565         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6566         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6567         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6568         touch $ref || error "touch $ref failed"
6569         # sleep 3 seconds at least
6570         sleep 3
6571
6572         local before=$(do_facet mds1 date +%s)
6573         local skew=$(($(date +%s) - before + 1))
6574
6575         if (( skew < 0 && skew > -5 )); then
6576                 sleep $((0 - skew + 1))
6577                 skew=0
6578         fi
6579
6580         # Set the dir stripe params to limit files all on MDT0,
6581         # otherwise we need to calc the max clock skew between
6582         # the client and MDTs.
6583         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6584         sleep 2
6585         touch $negref || error "touch $negref failed"
6586
6587         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6588         local nums=$($cmd | wc -l)
6589         local expected=$(((NUMFILES + 1) * NUMDIRS))
6590
6591         [ $nums -eq $expected ] ||
6592                 error "'$cmd' wrong: found $nums, expected $expected"
6593
6594         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6595         nums=$($cmd | wc -l)
6596         expected=$((NUMFILES + 1))
6597         [ $nums -eq $expected ] ||
6598                 error "'$cmd' wrong: found $nums, expected $expected"
6599
6600         [ $skew -lt 0 ] && return
6601
6602         local after=$(do_facet mds1 date +%s)
6603         local age=$((after - before + 1 + skew))
6604
6605         cmd="$LFS find $dir -btime -${age}s -type f"
6606         nums=$($cmd | wc -l)
6607         expected=$(((NUMFILES + 1) * NUMDIRS))
6608
6609         echo "Clock skew between client and server: $skew, age:$age"
6610         [ $nums -eq $expected ] ||
6611                 error "'$cmd' wrong: found $nums, expected $expected"
6612
6613         expected=$(($NUMDIRS + 1))
6614         cmd="$LFS find $dir -btime -${age}s -type d"
6615         nums=$($cmd | wc -l)
6616         [ $nums -eq $expected ] ||
6617                 error "'$cmd' wrong: found $nums, expected $expected"
6618         rm -f $ref $negref || error "Failed to remove $ref $negref"
6619 }
6620 run_test 56od "check lfs find -btime with units"
6621
6622 test_56p() {
6623         [ $RUNAS_ID -eq $UID ] &&
6624                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6625
6626         local dir=$DIR/$tdir
6627
6628         setup_56 $dir $NUMFILES $NUMDIRS
6629         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6630
6631         local expected=$NUMFILES
6632         local cmd="$LFS find -uid $RUNAS_ID $dir"
6633         local nums=$($cmd | wc -l)
6634
6635         [ $nums -eq $expected ] ||
6636                 error "'$cmd' wrong: found $nums, expected $expected"
6637
6638         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6639         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6640         nums=$($cmd | wc -l)
6641         [ $nums -eq $expected ] ||
6642                 error "'$cmd' wrong: found $nums, expected $expected"
6643 }
6644 run_test 56p "check lfs find -uid and ! -uid"
6645
6646 test_56q() {
6647         [ $RUNAS_ID -eq $UID ] &&
6648                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6649
6650         local dir=$DIR/$tdir
6651
6652         setup_56 $dir $NUMFILES $NUMDIRS
6653         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6654
6655         local expected=$NUMFILES
6656         local cmd="$LFS find -gid $RUNAS_GID $dir"
6657         local nums=$($cmd | wc -l)
6658
6659         [ $nums -eq $expected ] ||
6660                 error "'$cmd' wrong: found $nums, expected $expected"
6661
6662         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6663         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6664         nums=$($cmd | wc -l)
6665         [ $nums -eq $expected ] ||
6666                 error "'$cmd' wrong: found $nums, expected $expected"
6667 }
6668 run_test 56q "check lfs find -gid and ! -gid"
6669
6670 test_56r() {
6671         local dir=$DIR/$tdir
6672
6673         setup_56 $dir $NUMFILES $NUMDIRS
6674
6675         local expected=12
6676         local cmd="$LFS find -size 0 -type f -lazy $dir"
6677         local nums=$($cmd | wc -l)
6678
6679         [ $nums -eq $expected ] ||
6680                 error "'$cmd' wrong: found $nums, expected $expected"
6681         cmd="$LFS find -size 0 -type f $dir"
6682         nums=$($cmd | wc -l)
6683         [ $nums -eq $expected ] ||
6684                 error "'$cmd' wrong: found $nums, expected $expected"
6685
6686         expected=0
6687         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6688         nums=$($cmd | wc -l)
6689         [ $nums -eq $expected ] ||
6690                 error "'$cmd' wrong: found $nums, expected $expected"
6691         cmd="$LFS find ! -size 0 -type f $dir"
6692         nums=$($cmd | wc -l)
6693         [ $nums -eq $expected ] ||
6694                 error "'$cmd' wrong: found $nums, expected $expected"
6695
6696         echo "test" > $dir/$tfile
6697         echo "test2" > $dir/$tfile.2 && sync
6698         expected=1
6699         cmd="$LFS find -size 5 -type f -lazy $dir"
6700         nums=$($cmd | wc -l)
6701         [ $nums -eq $expected ] ||
6702                 error "'$cmd' wrong: found $nums, expected $expected"
6703         cmd="$LFS find -size 5 -type f $dir"
6704         nums=$($cmd | wc -l)
6705         [ $nums -eq $expected ] ||
6706                 error "'$cmd' wrong: found $nums, expected $expected"
6707
6708         expected=1
6709         cmd="$LFS find -size +5 -type f -lazy $dir"
6710         nums=$($cmd | wc -l)
6711         [ $nums -eq $expected ] ||
6712                 error "'$cmd' wrong: found $nums, expected $expected"
6713         cmd="$LFS find -size +5 -type f $dir"
6714         nums=$($cmd | wc -l)
6715         [ $nums -eq $expected ] ||
6716                 error "'$cmd' wrong: found $nums, expected $expected"
6717
6718         expected=2
6719         cmd="$LFS find -size +0 -type f -lazy $dir"
6720         nums=$($cmd | wc -l)
6721         [ $nums -eq $expected ] ||
6722                 error "'$cmd' wrong: found $nums, expected $expected"
6723         cmd="$LFS find -size +0 -type f $dir"
6724         nums=$($cmd | wc -l)
6725         [ $nums -eq $expected ] ||
6726                 error "'$cmd' wrong: found $nums, expected $expected"
6727
6728         expected=2
6729         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6730         nums=$($cmd | wc -l)
6731         [ $nums -eq $expected ] ||
6732                 error "'$cmd' wrong: found $nums, expected $expected"
6733         cmd="$LFS find ! -size -5 -type f $dir"
6734         nums=$($cmd | wc -l)
6735         [ $nums -eq $expected ] ||
6736                 error "'$cmd' wrong: found $nums, expected $expected"
6737
6738         expected=12
6739         cmd="$LFS find -size -5 -type f -lazy $dir"
6740         nums=$($cmd | wc -l)
6741         [ $nums -eq $expected ] ||
6742                 error "'$cmd' wrong: found $nums, expected $expected"
6743         cmd="$LFS find -size -5 -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] ||
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747 }
6748 run_test 56r "check lfs find -size works"
6749
6750 test_56ra_sub() {
6751         local expected=$1
6752         local glimpses=$2
6753         local cmd="$3"
6754
6755         cancel_lru_locks $OSC
6756
6757         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6758         local nums=$($cmd | wc -l)
6759
6760         [ $nums -eq $expected ] ||
6761                 error "'$cmd' wrong: found $nums, expected $expected"
6762
6763         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6764
6765         if (( rpcs_before + glimpses != rpcs_after )); then
6766                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6767                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6768
6769                 if [[ $glimpses == 0 ]]; then
6770                         error "'$cmd' should not send glimpse RPCs to OST"
6771                 else
6772                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6773                 fi
6774         fi
6775 }
6776
6777 test_56ra() {
6778         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6779                 skip "MDS < 2.12.58 doesn't return LSOM data"
6780         local dir=$DIR/$tdir
6781         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6782
6783         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6784
6785         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6786         $LCTL set_param -n llite.*.statahead_agl=0
6787         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6788
6789         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6790         # open and close all files to ensure LSOM is updated
6791         cancel_lru_locks $OSC
6792         find $dir -type f | xargs cat > /dev/null
6793
6794         #   expect_found  glimpse_rpcs  command_to_run
6795         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6796         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6797         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6798         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6799
6800         echo "test" > $dir/$tfile
6801         echo "test2" > $dir/$tfile.2 && sync
6802         cancel_lru_locks $OSC
6803         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6804
6805         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6806         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6807         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6808         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6809
6810         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6811         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6812         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6813         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6814         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6815         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6816 }
6817 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6818
6819 test_56rb() {
6820         local dir=$DIR/$tdir
6821         local tmp=$TMP/$tfile.log
6822         local mdt_idx;
6823
6824         test_mkdir -p $dir || error "failed to mkdir $dir"
6825         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6826                 error "failed to setstripe $dir/$tfile"
6827         mdt_idx=$($LFS getdirstripe -i $dir)
6828         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6829
6830         stack_trap "rm -f $tmp" EXIT
6831         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6832         ! grep -q obd_uuid $tmp ||
6833                 error "failed to find --size +100K --ost 0 $dir"
6834         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6835         ! grep -q obd_uuid $tmp ||
6836                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6837 }
6838 run_test 56rb "check lfs find --size --ost/--mdt works"
6839
6840 test_56rc() {
6841         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6842         local dir=$DIR/$tdir
6843         local found
6844
6845         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6846         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6847         (( $MDSCOUNT > 2 )) &&
6848                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6849         mkdir $dir/$tdir-{1..10}
6850         touch $dir/$tfile-{1..10}
6851
6852         found=$($LFS find $dir --mdt-count 2 | wc -l)
6853         expect=11
6854         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6855
6856         found=$($LFS find $dir -T +1 | wc -l)
6857         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6858         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6859
6860         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6861         expect=11
6862         (( $found == $expect )) || error "found $found all_char, expect $expect"
6863
6864         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6865         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6866         (( $found == $expect )) || error "found $found all_char, expect $expect"
6867 }
6868 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6869
6870 test_56s() { # LU-611 #LU-9369
6871         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6872
6873         local dir=$DIR/$tdir
6874         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6875
6876         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6877         for i in $(seq $NUMDIRS); do
6878                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6879         done
6880
6881         local expected=$NUMDIRS
6882         local cmd="$LFS find -c $OSTCOUNT $dir"
6883         local nums=$($cmd | wc -l)
6884
6885         [ $nums -eq $expected ] || {
6886                 $LFS getstripe -R $dir
6887                 error "'$cmd' wrong: found $nums, expected $expected"
6888         }
6889
6890         expected=$((NUMDIRS + onestripe))
6891         cmd="$LFS find -stripe-count +0 -type f $dir"
6892         nums=$($cmd | wc -l)
6893         [ $nums -eq $expected ] || {
6894                 $LFS getstripe -R $dir
6895                 error "'$cmd' wrong: found $nums, expected $expected"
6896         }
6897
6898         expected=$onestripe
6899         cmd="$LFS find -stripe-count 1 -type f $dir"
6900         nums=$($cmd | wc -l)
6901         [ $nums -eq $expected ] || {
6902                 $LFS getstripe -R $dir
6903                 error "'$cmd' wrong: found $nums, expected $expected"
6904         }
6905
6906         cmd="$LFS find -stripe-count -2 -type f $dir"
6907         nums=$($cmd | wc -l)
6908         [ $nums -eq $expected ] || {
6909                 $LFS getstripe -R $dir
6910                 error "'$cmd' wrong: found $nums, expected $expected"
6911         }
6912
6913         expected=0
6914         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6915         nums=$($cmd | wc -l)
6916         [ $nums -eq $expected ] || {
6917                 $LFS getstripe -R $dir
6918                 error "'$cmd' wrong: found $nums, expected $expected"
6919         }
6920 }
6921 run_test 56s "check lfs find -stripe-count works"
6922
6923 test_56t() { # LU-611 #LU-9369
6924         local dir=$DIR/$tdir
6925
6926         setup_56 $dir 0 $NUMDIRS
6927         for i in $(seq $NUMDIRS); do
6928                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6929         done
6930
6931         local expected=$NUMDIRS
6932         local cmd="$LFS find -S 8M $dir"
6933         local nums=$($cmd | wc -l)
6934
6935         [ $nums -eq $expected ] || {
6936                 $LFS getstripe -R $dir
6937                 error "'$cmd' wrong: found $nums, expected $expected"
6938         }
6939         rm -rf $dir
6940
6941         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6942
6943         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6944
6945         expected=$(((NUMDIRS + 1) * NUMFILES))
6946         cmd="$LFS find -stripe-size 512k -type f $dir"
6947         nums=$($cmd | wc -l)
6948         [ $nums -eq $expected ] ||
6949                 error "'$cmd' wrong: found $nums, expected $expected"
6950
6951         cmd="$LFS find -stripe-size +320k -type f $dir"
6952         nums=$($cmd | wc -l)
6953         [ $nums -eq $expected ] ||
6954                 error "'$cmd' wrong: found $nums, expected $expected"
6955
6956         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6957         cmd="$LFS find -stripe-size +200k -type f $dir"
6958         nums=$($cmd | wc -l)
6959         [ $nums -eq $expected ] ||
6960                 error "'$cmd' wrong: found $nums, expected $expected"
6961
6962         cmd="$LFS find -stripe-size -640k -type f $dir"
6963         nums=$($cmd | wc -l)
6964         [ $nums -eq $expected ] ||
6965                 error "'$cmd' wrong: found $nums, expected $expected"
6966
6967         expected=4
6968         cmd="$LFS find -stripe-size 256k -type f $dir"
6969         nums=$($cmd | wc -l)
6970         [ $nums -eq $expected ] ||
6971                 error "'$cmd' wrong: found $nums, expected $expected"
6972
6973         cmd="$LFS find -stripe-size -320k -type f $dir"
6974         nums=$($cmd | wc -l)
6975         [ $nums -eq $expected ] ||
6976                 error "'$cmd' wrong: found $nums, expected $expected"
6977
6978         expected=0
6979         cmd="$LFS find -stripe-size 1024k -type f $dir"
6980         nums=$($cmd | wc -l)
6981         [ $nums -eq $expected ] ||
6982                 error "'$cmd' wrong: found $nums, expected $expected"
6983 }
6984 run_test 56t "check lfs find -stripe-size works"
6985
6986 test_56u() { # LU-611
6987         local dir=$DIR/$tdir
6988
6989         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6990
6991         if [[ $OSTCOUNT -gt 1 ]]; then
6992                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6993                 onestripe=4
6994         else
6995                 onestripe=0
6996         fi
6997
6998         local expected=$(((NUMDIRS + 1) * NUMFILES))
6999         local cmd="$LFS find -stripe-index 0 -type f $dir"
7000         local nums=$($cmd | wc -l)
7001
7002         [ $nums -eq $expected ] ||
7003                 error "'$cmd' wrong: found $nums, expected $expected"
7004
7005         expected=$onestripe
7006         cmd="$LFS find -stripe-index 1 -type f $dir"
7007         nums=$($cmd | wc -l)
7008         [ $nums -eq $expected ] ||
7009                 error "'$cmd' wrong: found $nums, expected $expected"
7010
7011         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7012         nums=$($cmd | wc -l)
7013         [ $nums -eq $expected ] ||
7014                 error "'$cmd' wrong: found $nums, expected $expected"
7015
7016         expected=0
7017         # This should produce an error and not return any files
7018         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7019         nums=$($cmd 2>/dev/null | wc -l)
7020         [ $nums -eq $expected ] ||
7021                 error "'$cmd' wrong: found $nums, expected $expected"
7022
7023         if [[ $OSTCOUNT -gt 1 ]]; then
7024                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7025                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7026                 nums=$($cmd | wc -l)
7027                 [ $nums -eq $expected ] ||
7028                         error "'$cmd' wrong: found $nums, expected $expected"
7029         fi
7030 }
7031 run_test 56u "check lfs find -stripe-index works"
7032
7033 test_56v() {
7034         local mdt_idx=0
7035         local dir=$DIR/$tdir
7036
7037         setup_56 $dir $NUMFILES $NUMDIRS
7038
7039         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7040         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7041
7042         for file in $($LFS find -m $UUID $dir); do
7043                 file_midx=$($LFS getstripe -m $file)
7044                 [ $file_midx -eq $mdt_idx ] ||
7045                         error "lfs find -m $UUID != getstripe -m $file_midx"
7046         done
7047 }
7048 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7049
7050 test_56w() {
7051         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7053
7054         local dir=$DIR/$tdir
7055
7056         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7057
7058         local stripe_size=$($LFS getstripe -S -d $dir) ||
7059                 error "$LFS getstripe -S -d $dir failed"
7060         stripe_size=${stripe_size%% *}
7061
7062         local file_size=$((stripe_size * OSTCOUNT))
7063         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7064         local required_space=$((file_num * file_size))
7065         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7066                            head -n1)
7067         [[ $free_space -le $((required_space / 1024)) ]] &&
7068                 skip_env "need $required_space, have $free_space kbytes"
7069
7070         local dd_bs=65536
7071         local dd_count=$((file_size / dd_bs))
7072
7073         # write data into the files
7074         local i
7075         local j
7076         local file
7077
7078         for i in $(seq $NUMFILES); do
7079                 file=$dir/file$i
7080                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7081                         error "write data into $file failed"
7082         done
7083         for i in $(seq $NUMDIRS); do
7084                 for j in $(seq $NUMFILES); do
7085                         file=$dir/dir$i/file$j
7086                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7087                                 error "write data into $file failed"
7088                 done
7089         done
7090
7091         # $LFS_MIGRATE will fail if hard link migration is unsupported
7092         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7093                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7094                         error "creating links to $dir/dir1/file1 failed"
7095         fi
7096
7097         local expected=-1
7098
7099         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7100
7101         # lfs_migrate file
7102         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7103
7104         echo "$cmd"
7105         eval $cmd || error "$cmd failed"
7106
7107         check_stripe_count $dir/file1 $expected
7108
7109         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7110         then
7111                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7112                 # OST 1 if it is on OST 0. This file is small enough to
7113                 # be on only one stripe.
7114                 file=$dir/migr_1_ost
7115                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7116                         error "write data into $file failed"
7117                 local obdidx=$($LFS getstripe -i $file)
7118                 local oldmd5=$(md5sum $file)
7119                 local newobdidx=0
7120
7121                 [[ $obdidx -eq 0 ]] && newobdidx=1
7122                 cmd="$LFS migrate -i $newobdidx $file"
7123                 echo $cmd
7124                 eval $cmd || error "$cmd failed"
7125
7126                 local realobdix=$($LFS getstripe -i $file)
7127                 local newmd5=$(md5sum $file)
7128
7129                 [[ $newobdidx -ne $realobdix ]] &&
7130                         error "new OST is different (was=$obdidx, "\
7131                               "wanted=$newobdidx, got=$realobdix)"
7132                 [[ "$oldmd5" != "$newmd5" ]] &&
7133                         error "md5sum differ: $oldmd5, $newmd5"
7134         fi
7135
7136         # lfs_migrate dir
7137         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7138         echo "$cmd"
7139         eval $cmd || error "$cmd failed"
7140
7141         for j in $(seq $NUMFILES); do
7142                 check_stripe_count $dir/dir1/file$j $expected
7143         done
7144
7145         # lfs_migrate works with lfs find
7146         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7147              $LFS_MIGRATE -y -c $expected"
7148         echo "$cmd"
7149         eval $cmd || error "$cmd failed"
7150
7151         for i in $(seq 2 $NUMFILES); do
7152                 check_stripe_count $dir/file$i $expected
7153         done
7154         for i in $(seq 2 $NUMDIRS); do
7155                 for j in $(seq $NUMFILES); do
7156                 check_stripe_count $dir/dir$i/file$j $expected
7157                 done
7158         done
7159 }
7160 run_test 56w "check lfs_migrate -c stripe_count works"
7161
7162 test_56wb() {
7163         local file1=$DIR/$tdir/file1
7164         local create_pool=false
7165         local initial_pool=$($LFS getstripe -p $DIR)
7166         local pool_list=()
7167         local pool=""
7168
7169         echo -n "Creating test dir..."
7170         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7171         echo "done."
7172
7173         echo -n "Creating test file..."
7174         touch $file1 || error "cannot create file"
7175         echo "done."
7176
7177         echo -n "Detecting existing pools..."
7178         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7179
7180         if [ ${#pool_list[@]} -gt 0 ]; then
7181                 echo "${pool_list[@]}"
7182                 for thispool in "${pool_list[@]}"; do
7183                         if [[ -z "$initial_pool" ||
7184                               "$initial_pool" != "$thispool" ]]; then
7185                                 pool="$thispool"
7186                                 echo "Using existing pool '$pool'"
7187                                 break
7188                         fi
7189                 done
7190         else
7191                 echo "none detected."
7192         fi
7193         if [ -z "$pool" ]; then
7194                 pool=${POOL:-testpool}
7195                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7196                 echo -n "Creating pool '$pool'..."
7197                 create_pool=true
7198                 pool_add $pool &> /dev/null ||
7199                         error "pool_add failed"
7200                 echo "done."
7201
7202                 echo -n "Adding target to pool..."
7203                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7204                         error "pool_add_targets failed"
7205                 echo "done."
7206         fi
7207
7208         echo -n "Setting pool using -p option..."
7209         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7210                 error "migrate failed rc = $?"
7211         echo "done."
7212
7213         echo -n "Verifying test file is in pool after migrating..."
7214         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7215                 error "file was not migrated to pool $pool"
7216         echo "done."
7217
7218         echo -n "Removing test file from pool '$pool'..."
7219         # "lfs migrate $file" won't remove the file from the pool
7220         # until some striping information is changed.
7221         $LFS migrate -c 1 $file1 &> /dev/null ||
7222                 error "cannot remove from pool"
7223         [ "$($LFS getstripe -p $file1)" ] &&
7224                 error "pool still set"
7225         echo "done."
7226
7227         echo -n "Setting pool using --pool option..."
7228         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7229                 error "migrate failed rc = $?"
7230         echo "done."
7231
7232         # Clean up
7233         rm -f $file1
7234         if $create_pool; then
7235                 destroy_test_pools 2> /dev/null ||
7236                         error "destroy test pools failed"
7237         fi
7238 }
7239 run_test 56wb "check lfs_migrate pool support"
7240
7241 test_56wc() {
7242         local file1="$DIR/$tdir/file1"
7243         local parent_ssize
7244         local parent_scount
7245         local cur_ssize
7246         local cur_scount
7247         local orig_ssize
7248
7249         echo -n "Creating test dir..."
7250         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7251         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7252                 error "cannot set stripe by '-S 1M -c 1'"
7253         echo "done"
7254
7255         echo -n "Setting initial stripe for test file..."
7256         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7257                 error "cannot set stripe"
7258         cur_ssize=$($LFS getstripe -S "$file1")
7259         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7260         echo "done."
7261
7262         # File currently set to -S 512K -c 1
7263
7264         # Ensure -c and -S options are rejected when -R is set
7265         echo -n "Verifying incompatible options are detected..."
7266         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7267                 error "incompatible -c and -R options not detected"
7268         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7269                 error "incompatible -S and -R options not detected"
7270         echo "done."
7271
7272         # Ensure unrecognized options are passed through to 'lfs migrate'
7273         echo -n "Verifying -S option is passed through to lfs migrate..."
7274         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7275                 error "migration failed"
7276         cur_ssize=$($LFS getstripe -S "$file1")
7277         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7278         echo "done."
7279
7280         # File currently set to -S 1M -c 1
7281
7282         # Ensure long options are supported
7283         echo -n "Verifying long options supported..."
7284         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7285                 error "long option without argument not supported"
7286         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7287                 error "long option with argument not supported"
7288         cur_ssize=$($LFS getstripe -S "$file1")
7289         [ $cur_ssize -eq 524288 ] ||
7290                 error "migrate --stripe-size $cur_ssize != 524288"
7291         echo "done."
7292
7293         # File currently set to -S 512K -c 1
7294
7295         if [ "$OSTCOUNT" -gt 1 ]; then
7296                 echo -n "Verifying explicit stripe count can be set..."
7297                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7298                         error "migrate failed"
7299                 cur_scount=$($LFS getstripe -c "$file1")
7300                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7301                 echo "done."
7302         fi
7303
7304         # File currently set to -S 512K -c 1 or -S 512K -c 2
7305
7306         # Ensure parent striping is used if -R is set, and no stripe
7307         # count or size is specified
7308         echo -n "Setting stripe for parent directory..."
7309         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7310                 error "cannot set stripe '-S 2M -c 1'"
7311         echo "done."
7312
7313         echo -n "Verifying restripe option uses parent stripe settings..."
7314         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7315         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7316         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7317                 error "migrate failed"
7318         cur_ssize=$($LFS getstripe -S "$file1")
7319         [ $cur_ssize -eq $parent_ssize ] ||
7320                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7321         cur_scount=$($LFS getstripe -c "$file1")
7322         [ $cur_scount -eq $parent_scount ] ||
7323                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7324         echo "done."
7325
7326         # File currently set to -S 1M -c 1
7327
7328         # Ensure striping is preserved if -R is not set, and no stripe
7329         # count or size is specified
7330         echo -n "Verifying striping size preserved when not specified..."
7331         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7332         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7333                 error "cannot set stripe on parent directory"
7334         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7335                 error "migrate failed"
7336         cur_ssize=$($LFS getstripe -S "$file1")
7337         [ $cur_ssize -eq $orig_ssize ] ||
7338                 error "migrate by default $cur_ssize != $orig_ssize"
7339         echo "done."
7340
7341         # Ensure file name properly detected when final option has no argument
7342         echo -n "Verifying file name properly detected..."
7343         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7344                 error "file name interpreted as option argument"
7345         echo "done."
7346
7347         # Clean up
7348         rm -f "$file1"
7349 }
7350 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7351
7352 test_56wd() {
7353         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7354
7355         local file1=$DIR/$tdir/file1
7356
7357         echo -n "Creating test dir..."
7358         test_mkdir $DIR/$tdir || error "cannot create dir"
7359         echo "done."
7360
7361         echo -n "Creating test file..."
7362         touch $file1
7363         echo "done."
7364
7365         # Ensure 'lfs migrate' will fail by using a non-existent option,
7366         # and make sure rsync is not called to recover
7367         echo -n "Make sure --no-rsync option works..."
7368         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7369                 grep -q 'refusing to fall back to rsync' ||
7370                 error "rsync was called with --no-rsync set"
7371         echo "done."
7372
7373         # Ensure rsync is called without trying 'lfs migrate' first
7374         echo -n "Make sure --rsync option works..."
7375         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7376                 grep -q 'falling back to rsync' &&
7377                 error "lfs migrate was called with --rsync set"
7378         echo "done."
7379
7380         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7381         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7382                 grep -q 'at the same time' ||
7383                 error "--rsync and --no-rsync accepted concurrently"
7384         echo "done."
7385
7386         # Clean up
7387         rm -f $file1
7388 }
7389 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7390
7391 test_56we() {
7392         local td=$DIR/$tdir
7393         local tf=$td/$tfile
7394
7395         test_mkdir $td || error "cannot create $td"
7396         touch $tf || error "cannot touch $tf"
7397
7398         echo -n "Make sure --non-direct|-D works..."
7399         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7400                 grep -q "lfs migrate --non-direct" ||
7401                 error "--non-direct option cannot work correctly"
7402         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7403                 grep -q "lfs migrate -D" ||
7404                 error "-D option cannot work correctly"
7405         echo "done."
7406 }
7407 run_test 56we "check lfs_migrate --non-direct|-D support"
7408
7409 test_56x() {
7410         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7411         check_swap_layouts_support
7412
7413         local dir=$DIR/$tdir
7414         local ref1=/etc/passwd
7415         local file1=$dir/file1
7416
7417         test_mkdir $dir || error "creating dir $dir"
7418         $LFS setstripe -c 2 $file1
7419         cp $ref1 $file1
7420         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7421         stripe=$($LFS getstripe -c $file1)
7422         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7423         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7424
7425         # clean up
7426         rm -f $file1
7427 }
7428 run_test 56x "lfs migration support"
7429
7430 test_56xa() {
7431         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7432         check_swap_layouts_support
7433
7434         local dir=$DIR/$tdir/$testnum
7435
7436         test_mkdir -p $dir
7437
7438         local ref1=/etc/passwd
7439         local file1=$dir/file1
7440
7441         $LFS setstripe -c 2 $file1
7442         cp $ref1 $file1
7443         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7444
7445         local stripe=$($LFS getstripe -c $file1)
7446
7447         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7448         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7449
7450         # clean up
7451         rm -f $file1
7452 }
7453 run_test 56xa "lfs migration --block support"
7454
7455 check_migrate_links() {
7456         local dir="$1"
7457         local file1="$dir/file1"
7458         local begin="$2"
7459         local count="$3"
7460         local runas="$4"
7461         local total_count=$(($begin + $count - 1))
7462         local symlink_count=10
7463         local uniq_count=10
7464
7465         if [ ! -f "$file1" ]; then
7466                 echo -n "creating initial file..."
7467                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7468                         error "cannot setstripe initial file"
7469                 echo "done"
7470
7471                 echo -n "creating symlinks..."
7472                 for s in $(seq 1 $symlink_count); do
7473                         ln -s "$file1" "$dir/slink$s" ||
7474                                 error "cannot create symlinks"
7475                 done
7476                 echo "done"
7477
7478                 echo -n "creating nonlinked files..."
7479                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7480                         error "cannot create nonlinked files"
7481                 echo "done"
7482         fi
7483
7484         # create hard links
7485         if [ ! -f "$dir/file$total_count" ]; then
7486                 echo -n "creating hard links $begin:$total_count..."
7487                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7488                         /dev/null || error "cannot create hard links"
7489                 echo "done"
7490         fi
7491
7492         echo -n "checking number of hard links listed in xattrs..."
7493         local fid=$($LFS getstripe -F "$file1")
7494         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7495
7496         echo "${#paths[*]}"
7497         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7498                         skip "hard link list has unexpected size, skipping test"
7499         fi
7500         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7501                         error "link names should exceed xattrs size"
7502         fi
7503
7504         echo -n "migrating files..."
7505         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7506         local rc=$?
7507         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7508         echo "done"
7509
7510         # make sure all links have been properly migrated
7511         echo -n "verifying files..."
7512         fid=$($LFS getstripe -F "$file1") ||
7513                 error "cannot get fid for file $file1"
7514         for i in $(seq 2 $total_count); do
7515                 local fid2=$($LFS getstripe -F $dir/file$i)
7516
7517                 [ "$fid2" == "$fid" ] ||
7518                         error "migrated hard link has mismatched FID"
7519         done
7520
7521         # make sure hard links were properly detected, and migration was
7522         # performed only once for the entire link set; nonlinked files should
7523         # also be migrated
7524         local actual=$(grep -c 'done' <<< "$migrate_out")
7525         local expected=$(($uniq_count + 1))
7526
7527         [ "$actual" -eq  "$expected" ] ||
7528                 error "hard links individually migrated ($actual != $expected)"
7529
7530         # make sure the correct number of hard links are present
7531         local hardlinks=$(stat -c '%h' "$file1")
7532
7533         [ $hardlinks -eq $total_count ] ||
7534                 error "num hard links $hardlinks != $total_count"
7535         echo "done"
7536
7537         return 0
7538 }
7539
7540 test_56xb() {
7541         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7542                 skip "Need MDS version at least 2.10.55"
7543
7544         local dir="$DIR/$tdir"
7545
7546         test_mkdir "$dir" || error "cannot create dir $dir"
7547
7548         echo "testing lfs migrate mode when all links fit within xattrs"
7549         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7550
7551         echo "testing rsync mode when all links fit within xattrs"
7552         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7553
7554         echo "testing lfs migrate mode when all links do not fit within xattrs"
7555         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7556
7557         echo "testing rsync mode when all links do not fit within xattrs"
7558         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7559
7560         chown -R $RUNAS_ID $dir
7561         echo "testing non-root lfs migrate mode when not all links are in xattr"
7562         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7563
7564         # clean up
7565         rm -rf $dir
7566 }
7567 run_test 56xb "lfs migration hard link support"
7568
7569 test_56xc() {
7570         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7571
7572         local dir="$DIR/$tdir"
7573
7574         test_mkdir "$dir" || error "cannot create dir $dir"
7575
7576         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7577         echo -n "Setting initial stripe for 20MB test file..."
7578         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7579                 error "cannot setstripe 20MB file"
7580         echo "done"
7581         echo -n "Sizing 20MB test file..."
7582         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7583         echo "done"
7584         echo -n "Verifying small file autostripe count is 1..."
7585         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7586                 error "cannot migrate 20MB file"
7587         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7588                 error "cannot get stripe for $dir/20mb"
7589         [ $stripe_count -eq 1 ] ||
7590                 error "unexpected stripe count $stripe_count for 20MB file"
7591         rm -f "$dir/20mb"
7592         echo "done"
7593
7594         # Test 2: File is small enough to fit within the available space on
7595         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7596         # have at least an additional 1KB for each desired stripe for test 3
7597         echo -n "Setting stripe for 1GB test file..."
7598         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7599         echo "done"
7600         echo -n "Sizing 1GB test file..."
7601         # File size is 1GB + 3KB
7602         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7603         echo "done"
7604
7605         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7606         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7607         if (( avail > 524288 * OSTCOUNT )); then
7608                 echo -n "Migrating 1GB file..."
7609                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7610                         error "cannot migrate 1GB file"
7611                 echo "done"
7612                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7613                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7614                         error "cannot getstripe for 1GB file"
7615                 [ $stripe_count -eq 2 ] ||
7616                         error "unexpected stripe count $stripe_count != 2"
7617                 echo "done"
7618         fi
7619
7620         # Test 3: File is too large to fit within the available space on
7621         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7622         if [ $OSTCOUNT -ge 3 ]; then
7623                 # The required available space is calculated as
7624                 # file size (1GB + 3KB) / OST count (3).
7625                 local kb_per_ost=349526
7626
7627                 echo -n "Migrating 1GB file with limit..."
7628                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7629                         error "cannot migrate 1GB file with limit"
7630                 echo "done"
7631
7632                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7633                 echo -n "Verifying 1GB autostripe count with limited space..."
7634                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7635                         error "unexpected stripe count $stripe_count (min 3)"
7636                 echo "done"
7637         fi
7638
7639         # clean up
7640         rm -rf $dir
7641 }
7642 run_test 56xc "lfs migration autostripe"
7643
7644 test_56xd() {
7645         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7646
7647         local dir=$DIR/$tdir
7648         local f_mgrt=$dir/$tfile.mgrt
7649         local f_yaml=$dir/$tfile.yaml
7650         local f_copy=$dir/$tfile.copy
7651         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7652         local layout_copy="-c 2 -S 2M -i 1"
7653         local yamlfile=$dir/yamlfile
7654         local layout_before;
7655         local layout_after;
7656
7657         test_mkdir "$dir" || error "cannot create dir $dir"
7658         $LFS setstripe $layout_yaml $f_yaml ||
7659                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7660         $LFS getstripe --yaml $f_yaml > $yamlfile
7661         $LFS setstripe $layout_copy $f_copy ||
7662                 error "cannot setstripe $f_copy with layout $layout_copy"
7663         touch $f_mgrt
7664         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7665
7666         # 1. test option --yaml
7667         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7668                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7669         layout_before=$(get_layout_param $f_yaml)
7670         layout_after=$(get_layout_param $f_mgrt)
7671         [ "$layout_after" == "$layout_before" ] ||
7672                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7673
7674         # 2. test option --copy
7675         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7676                 error "cannot migrate $f_mgrt with --copy $f_copy"
7677         layout_before=$(get_layout_param $f_copy)
7678         layout_after=$(get_layout_param $f_mgrt)
7679         [ "$layout_after" == "$layout_before" ] ||
7680                 error "lfs_migrate --copy: $layout_after != $layout_before"
7681 }
7682 run_test 56xd "check lfs_migrate --yaml and --copy support"
7683
7684 test_56xe() {
7685         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7686
7687         local dir=$DIR/$tdir
7688         local f_comp=$dir/$tfile
7689         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7690         local layout_before=""
7691         local layout_after=""
7692
7693         test_mkdir "$dir" || error "cannot create dir $dir"
7694         $LFS setstripe $layout $f_comp ||
7695                 error "cannot setstripe $f_comp with layout $layout"
7696         layout_before=$(get_layout_param $f_comp)
7697         dd if=/dev/zero of=$f_comp bs=1M count=4
7698
7699         # 1. migrate a comp layout file by lfs_migrate
7700         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7701         layout_after=$(get_layout_param $f_comp)
7702         [ "$layout_before" == "$layout_after" ] ||
7703                 error "lfs_migrate: $layout_before != $layout_after"
7704
7705         # 2. migrate a comp layout file by lfs migrate
7706         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7707         layout_after=$(get_layout_param $f_comp)
7708         [ "$layout_before" == "$layout_after" ] ||
7709                 error "lfs migrate: $layout_before != $layout_after"
7710 }
7711 run_test 56xe "migrate a composite layout file"
7712
7713 test_56xf() {
7714         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7715
7716         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7717                 skip "Need server version at least 2.13.53"
7718
7719         local dir=$DIR/$tdir
7720         local f_comp=$dir/$tfile
7721         local layout="-E 1M -c1 -E -1 -c2"
7722         local fid_before=""
7723         local fid_after=""
7724
7725         test_mkdir "$dir" || error "cannot create dir $dir"
7726         $LFS setstripe $layout $f_comp ||
7727                 error "cannot setstripe $f_comp with layout $layout"
7728         fid_before=$($LFS getstripe --fid $f_comp)
7729         dd if=/dev/zero of=$f_comp bs=1M count=4
7730
7731         # 1. migrate a comp layout file to a comp layout
7732         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7733         fid_after=$($LFS getstripe --fid $f_comp)
7734         [ "$fid_before" == "$fid_after" ] ||
7735                 error "comp-to-comp migrate: $fid_before != $fid_after"
7736
7737         # 2. migrate a comp layout file to a plain layout
7738         $LFS migrate -c2 $f_comp ||
7739                 error "cannot migrate $f_comp by lfs migrate"
7740         fid_after=$($LFS getstripe --fid $f_comp)
7741         [ "$fid_before" == "$fid_after" ] ||
7742                 error "comp-to-plain migrate: $fid_before != $fid_after"
7743
7744         # 3. migrate a plain layout file to a comp layout
7745         $LFS migrate $layout $f_comp ||
7746                 error "cannot migrate $f_comp by lfs migrate"
7747         fid_after=$($LFS getstripe --fid $f_comp)
7748         [ "$fid_before" == "$fid_after" ] ||
7749                 error "plain-to-comp migrate: $fid_before != $fid_after"
7750 }
7751 run_test 56xf "FID is not lost during migration of a composite layout file"
7752
7753 check_file_ost_range() {
7754         local file="$1"
7755         shift
7756         local range="$*"
7757         local -a file_range
7758         local idx
7759
7760         file_range=($($LFS getstripe -y "$file" |
7761                 awk '/l_ost_idx:/ { print $NF }'))
7762
7763         if [[ "${#file_range[@]}" = 0 ]]; then
7764                 echo "No osts found for $file"
7765                 return 1
7766         fi
7767
7768         for idx in "${file_range[@]}"; do
7769                 [[ " $range " =~ " $idx " ]] ||
7770                         return 1
7771         done
7772
7773         return 0
7774 }
7775
7776 sub_test_56xg() {
7777         local stripe_opt="$1"
7778         local pool="$2"
7779         shift 2
7780         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7781
7782         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7783                 error "Fail to migrate $tfile on $pool"
7784         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7785                 error "$tfile is not in pool $pool"
7786         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7787                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7788 }
7789
7790 test_56xg() {
7791         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7792         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7793         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7794                 skip "Need MDS version newer than 2.14.52"
7795
7796         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7797         local -a pool_ranges=("0 0" "1 1" "0 1")
7798
7799         # init pools
7800         for i in "${!pool_names[@]}"; do
7801                 pool_add ${pool_names[$i]} ||
7802                         error "pool_add failed (pool: ${pool_names[$i]})"
7803                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7804                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7805         done
7806
7807         # init the file to migrate
7808         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7809                 error "Unable to create $tfile on OST1"
7810         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7811                 error "Unable to write on $tfile"
7812
7813         echo "1. migrate $tfile on pool ${pool_names[0]}"
7814         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7815
7816         echo "2. migrate $tfile on pool ${pool_names[2]}"
7817         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7818
7819         echo "3. migrate $tfile on pool ${pool_names[1]}"
7820         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7821
7822         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7823         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7824         echo
7825
7826         # Clean pools
7827         destroy_test_pools ||
7828                 error "pool_destroy failed"
7829 }
7830 run_test 56xg "lfs migrate pool support"
7831
7832 test_56y() {
7833         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7834                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7835
7836         local res=""
7837         local dir=$DIR/$tdir
7838         local f1=$dir/file1
7839         local f2=$dir/file2
7840
7841         test_mkdir -p $dir || error "creating dir $dir"
7842         touch $f1 || error "creating std file $f1"
7843         $MULTIOP $f2 H2c || error "creating released file $f2"
7844
7845         # a directory can be raid0, so ask only for files
7846         res=$($LFS find $dir -L raid0 -type f | wc -l)
7847         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7848
7849         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7850         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7851
7852         # only files can be released, so no need to force file search
7853         res=$($LFS find $dir -L released)
7854         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7855
7856         res=$($LFS find $dir -type f \! -L released)
7857         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7858 }
7859 run_test 56y "lfs find -L raid0|released"
7860
7861 test_56z() { # LU-4824
7862         # This checks to make sure 'lfs find' continues after errors
7863         # There are two classes of errors that should be caught:
7864         # - If multiple paths are provided, all should be searched even if one
7865         #   errors out
7866         # - If errors are encountered during the search, it should not terminate
7867         #   early
7868         local dir=$DIR/$tdir
7869         local i
7870
7871         test_mkdir $dir
7872         for i in d{0..9}; do
7873                 test_mkdir $dir/$i
7874                 touch $dir/$i/$tfile
7875         done
7876         $LFS find $DIR/non_existent_dir $dir &&
7877                 error "$LFS find did not return an error"
7878         # Make a directory unsearchable. This should NOT be the last entry in
7879         # directory order.  Arbitrarily pick the 6th entry
7880         chmod 700 $($LFS find $dir -type d | sed '6!d')
7881
7882         $RUNAS $LFS find $DIR/non_existent $dir
7883         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7884
7885         # The user should be able to see 10 directories and 9 files
7886         (( count == 19 )) ||
7887                 error "$LFS find found $count != 19 entries after error"
7888 }
7889 run_test 56z "lfs find should continue after an error"
7890
7891 test_56aa() { # LU-5937
7892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7893
7894         local dir=$DIR/$tdir
7895
7896         mkdir $dir
7897         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7898
7899         createmany -o $dir/striped_dir/${tfile}- 1024
7900         local dirs=$($LFS find --size +8k $dir/)
7901
7902         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7903 }
7904 run_test 56aa "lfs find --size under striped dir"
7905
7906 test_56ab() { # LU-10705
7907         test_mkdir $DIR/$tdir
7908         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7909         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7910         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7911         # Flush writes to ensure valid blocks.  Need to be more thorough for
7912         # ZFS, since blocks are not allocated/returned to client immediately.
7913         sync_all_data
7914         wait_zfs_commit ost1 2
7915         cancel_lru_locks osc
7916         ls -ls $DIR/$tdir
7917
7918         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7919
7920         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7921
7922         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7923         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7924
7925         rm -f $DIR/$tdir/$tfile.[123]
7926 }
7927 run_test 56ab "lfs find --blocks"
7928
7929 # LU-11188
7930 test_56aca() {
7931         local dir="$DIR/$tdir"
7932         local perms=(001 002 003 004 005 006 007
7933                      010 020 030 040 050 060 070
7934                      100 200 300 400 500 600 700
7935                      111 222 333 444 555 666 777)
7936         local perm_minus=(8 8 4 8 4 4 2
7937                           8 8 4 8 4 4 2
7938                           8 8 4 8 4 4 2
7939                           4 4 2 4 2 2 1)
7940         local perm_slash=(8  8 12  8 12 12 14
7941                           8  8 12  8 12 12 14
7942                           8  8 12  8 12 12 14
7943                          16 16 24 16 24 24 28)
7944
7945         test_mkdir "$dir"
7946         for perm in ${perms[*]}; do
7947                 touch "$dir/$tfile.$perm"
7948                 chmod $perm "$dir/$tfile.$perm"
7949         done
7950
7951         for ((i = 0; i < ${#perms[*]}; i++)); do
7952                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7953                 (( $num == 1 )) ||
7954                         error "lfs find -perm ${perms[i]}:"\
7955                               "$num != 1"
7956
7957                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7958                 (( $num == ${perm_minus[i]} )) ||
7959                         error "lfs find -perm -${perms[i]}:"\
7960                               "$num != ${perm_minus[i]}"
7961
7962                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7963                 (( $num == ${perm_slash[i]} )) ||
7964                         error "lfs find -perm /${perms[i]}:"\
7965                               "$num != ${perm_slash[i]}"
7966         done
7967 }
7968 run_test 56aca "check lfs find -perm with octal representation"
7969
7970 test_56acb() {
7971         local dir=$DIR/$tdir
7972         # p is the permission of write and execute for user, group and other
7973         # without the umask. It is used to test +wx.
7974         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7975         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7976         local symbolic=(+t  a+t u+t g+t o+t
7977                         g+s u+s o+s +s o+sr
7978                         o=r,ug+o,u+w
7979                         u+ g+ o+ a+ ugo+
7980                         u- g- o- a- ugo-
7981                         u= g= o= a= ugo=
7982                         o=r,ug+o,u+w u=r,a+u,u+w
7983                         g=r,ugo=g,u+w u+x,+X +X
7984                         u+x,u+X u+X u+x,g+X o+r,+X
7985                         u+x,go+X +wx +rwx)
7986
7987         test_mkdir $dir
7988         for perm in ${perms[*]}; do
7989                 touch "$dir/$tfile.$perm"
7990                 chmod $perm "$dir/$tfile.$perm"
7991         done
7992
7993         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7994                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7995
7996                 (( $num == 1 )) ||
7997                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7998         done
7999 }
8000 run_test 56acb "check lfs find -perm with symbolic representation"
8001
8002 test_56acc() {
8003         local dir=$DIR/$tdir
8004         local tests="17777 787 789 abcd
8005                 ug=uu ug=a ug=gu uo=ou urw
8006                 u+xg+x a=r,u+x,"
8007
8008         test_mkdir $dir
8009         for err in $tests; do
8010                 if $LFS find $dir -perm $err 2>/dev/null; then
8011                         error "lfs find -perm $err: parsing should have failed"
8012                 fi
8013         done
8014 }
8015 run_test 56acc "check parsing error for lfs find -perm"
8016
8017 test_56ba() {
8018         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8019                 skip "Need MDS version at least 2.10.50"
8020
8021         # Create composite files with one component
8022         local dir=$DIR/$tdir
8023
8024         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8025         # Create composite files with three components
8026         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8027         # Create non-composite files
8028         createmany -o $dir/${tfile}- 10
8029
8030         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8031
8032         [[ $nfiles == 10 ]] ||
8033                 error "lfs find -E 1M found $nfiles != 10 files"
8034
8035         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8036         [[ $nfiles == 25 ]] ||
8037                 error "lfs find ! -E 1M found $nfiles != 25 files"
8038
8039         # All files have a component that starts at 0
8040         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8041         [[ $nfiles == 35 ]] ||
8042                 error "lfs find --component-start 0 - $nfiles != 35 files"
8043
8044         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8045         [[ $nfiles == 15 ]] ||
8046                 error "lfs find --component-start 2M - $nfiles != 15 files"
8047
8048         # All files created here have a componenet that does not starts at 2M
8049         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8050         [[ $nfiles == 35 ]] ||
8051                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8052
8053         # Find files with a specified number of components
8054         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8055         [[ $nfiles == 15 ]] ||
8056                 error "lfs find --component-count 3 - $nfiles != 15 files"
8057
8058         # Remember non-composite files have a component count of zero
8059         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8060         [[ $nfiles == 10 ]] ||
8061                 error "lfs find --component-count 0 - $nfiles != 10 files"
8062
8063         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8064         [[ $nfiles == 20 ]] ||
8065                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8066
8067         # All files have a flag called "init"
8068         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8069         [[ $nfiles == 35 ]] ||
8070                 error "lfs find --component-flags init - $nfiles != 35 files"
8071
8072         # Multi-component files will have a component not initialized
8073         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8074         [[ $nfiles == 15 ]] ||
8075                 error "lfs find !--component-flags init - $nfiles != 15 files"
8076
8077         rm -rf $dir
8078
8079 }
8080 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8081
8082 test_56ca() {
8083         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8084                 skip "Need MDS version at least 2.10.57"
8085
8086         local td=$DIR/$tdir
8087         local tf=$td/$tfile
8088         local dir
8089         local nfiles
8090         local cmd
8091         local i
8092         local j
8093
8094         # create mirrored directories and mirrored files
8095         mkdir $td || error "mkdir $td failed"
8096         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8097         createmany -o $tf- 10 || error "create $tf- failed"
8098
8099         for i in $(seq 2); do
8100                 dir=$td/dir$i
8101                 mkdir $dir || error "mkdir $dir failed"
8102                 $LFS mirror create -N$((3 + i)) $dir ||
8103                         error "create mirrored dir $dir failed"
8104                 createmany -o $dir/$tfile- 10 ||
8105                         error "create $dir/$tfile- failed"
8106         done
8107
8108         # change the states of some mirrored files
8109         echo foo > $tf-6
8110         for i in $(seq 2); do
8111                 dir=$td/dir$i
8112                 for j in $(seq 4 9); do
8113                         echo foo > $dir/$tfile-$j
8114                 done
8115         done
8116
8117         # find mirrored files with specific mirror count
8118         cmd="$LFS find --mirror-count 3 --type f $td"
8119         nfiles=$($cmd | wc -l)
8120         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8121
8122         cmd="$LFS find ! --mirror-count 3 --type f $td"
8123         nfiles=$($cmd | wc -l)
8124         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8125
8126         cmd="$LFS find --mirror-count +2 --type f $td"
8127         nfiles=$($cmd | wc -l)
8128         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8129
8130         cmd="$LFS find --mirror-count -6 --type f $td"
8131         nfiles=$($cmd | wc -l)
8132         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8133
8134         # find mirrored files with specific file state
8135         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8136         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8137
8138         cmd="$LFS find --mirror-state=ro --type f $td"
8139         nfiles=$($cmd | wc -l)
8140         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8141
8142         cmd="$LFS find ! --mirror-state=ro --type f $td"
8143         nfiles=$($cmd | wc -l)
8144         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8145
8146         cmd="$LFS find --mirror-state=wp --type f $td"
8147         nfiles=$($cmd | wc -l)
8148         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8149
8150         cmd="$LFS find ! --mirror-state=sp --type f $td"
8151         nfiles=$($cmd | wc -l)
8152         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8153 }
8154 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8155
8156 test_56da() { # LU-14179
8157         local path=$DIR/$tdir
8158
8159         test_mkdir $path
8160         cd $path
8161
8162         local longdir=$(str_repeat 'a' 255)
8163
8164         for i in {1..15}; do
8165                 path=$path/$longdir
8166                 test_mkdir $longdir
8167                 cd $longdir
8168         done
8169
8170         local len=${#path}
8171         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8172
8173         test_mkdir $lastdir
8174         cd $lastdir
8175         # PATH_MAX-1
8176         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8177
8178         # NAME_MAX
8179         touch $(str_repeat 'f' 255)
8180
8181         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8182                 error "lfs find reported an error"
8183
8184         rm -rf $DIR/$tdir
8185 }
8186 run_test 56da "test lfs find with long paths"
8187
8188 test_56ea() { #LU-10378
8189         local path=$DIR/$tdir
8190         local pool=$TESTNAME
8191
8192         # Create ost pool
8193         pool_add $pool || error "pool_add $pool failed"
8194         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8195                 error "adding targets to $pool failed"
8196
8197         # Set default pool on directory before creating file
8198         mkdir $path || error "mkdir $path failed"
8199         $LFS setstripe -p $pool $path ||
8200                 error "set OST pool on $pool failed"
8201         touch $path/$tfile || error "touch $path/$tfile failed"
8202
8203         # Compare basic file attributes from -printf and stat
8204         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8205         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8206
8207         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8208                 error "Attrs from lfs find and stat don't match"
8209
8210         # Compare Lustre attributes from lfs find and lfs getstripe
8211         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8212         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8213         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8214         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8215         local fpool=$($LFS getstripe --pool $path/$tfile)
8216         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8217
8218         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8219                 error "Attrs from lfs find and lfs getstripe don't match"
8220
8221         # Verify behavior for unknown escape/format sequences
8222         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8223
8224         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8225                 error "Escape/format codes don't match"
8226 }
8227 run_test 56ea "test lfs find -printf option"
8228
8229 test_57a() {
8230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8231         # note test will not do anything if MDS is not local
8232         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8233                 skip_env "ldiskfs only test"
8234         fi
8235         remote_mds_nodsh && skip "remote MDS with nodsh"
8236
8237         local MNTDEV="osd*.*MDT*.mntdev"
8238         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8239         [ -z "$DEV" ] && error "can't access $MNTDEV"
8240         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8241                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8242                         error "can't access $DEV"
8243                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8244                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8245                 rm $TMP/t57a.dump
8246         done
8247 }
8248 run_test 57a "verify MDS filesystem created with large inodes =="
8249
8250 test_57b() {
8251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8252         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8253                 skip_env "ldiskfs only test"
8254         fi
8255         remote_mds_nodsh && skip "remote MDS with nodsh"
8256
8257         local dir=$DIR/$tdir
8258         local filecount=100
8259         local file1=$dir/f1
8260         local fileN=$dir/f$filecount
8261
8262         rm -rf $dir || error "removing $dir"
8263         test_mkdir -c1 $dir
8264         local mdtidx=$($LFS getstripe -m $dir)
8265         local mdtname=MDT$(printf %04x $mdtidx)
8266         local facet=mds$((mdtidx + 1))
8267
8268         echo "mcreating $filecount files"
8269         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8270
8271         # verify that files do not have EAs yet
8272         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8273                 error "$file1 has an EA"
8274         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8275                 error "$fileN has an EA"
8276
8277         sync
8278         sleep 1
8279         df $dir  #make sure we get new statfs data
8280         local mdsfree=$(do_facet $facet \
8281                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8282         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8283         local file
8284
8285         echo "opening files to create objects/EAs"
8286         for file in $(seq -f $dir/f%g 1 $filecount); do
8287                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8288                         error "opening $file"
8289         done
8290
8291         # verify that files have EAs now
8292         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8293         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8294
8295         sleep 1  #make sure we get new statfs data
8296         df $dir
8297         local mdsfree2=$(do_facet $facet \
8298                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8299         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8300
8301         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8302                 if [ "$mdsfree" != "$mdsfree2" ]; then
8303                         error "MDC before $mdcfree != after $mdcfree2"
8304                 else
8305                         echo "MDC before $mdcfree != after $mdcfree2"
8306                         echo "unable to confirm if MDS has large inodes"
8307                 fi
8308         fi
8309         rm -rf $dir
8310 }
8311 run_test 57b "default LOV EAs are stored inside large inodes ==="
8312
8313 test_58() {
8314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8315         [ -z "$(which wiretest 2>/dev/null)" ] &&
8316                         skip_env "could not find wiretest"
8317
8318         wiretest
8319 }
8320 run_test 58 "verify cross-platform wire constants =============="
8321
8322 test_59() {
8323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8324
8325         echo "touch 130 files"
8326         createmany -o $DIR/f59- 130
8327         echo "rm 130 files"
8328         unlinkmany $DIR/f59- 130
8329         sync
8330         # wait for commitment of removal
8331         wait_delete_completed
8332 }
8333 run_test 59 "verify cancellation of llog records async ========="
8334
8335 TEST60_HEAD="test_60 run $RANDOM"
8336 test_60a() {
8337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8338         remote_mgs_nodsh && skip "remote MGS with nodsh"
8339         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8340                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8341                         skip_env "missing subtest run-llog.sh"
8342
8343         log "$TEST60_HEAD - from kernel mode"
8344         do_facet mgs "$LCTL dk > /dev/null"
8345         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8346         do_facet mgs $LCTL dk > $TMP/$tfile
8347
8348         # LU-6388: test llog_reader
8349         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8350         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8351         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8352                         skip_env "missing llog_reader"
8353         local fstype=$(facet_fstype mgs)
8354         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8355                 skip_env "Only for ldiskfs or zfs type mgs"
8356
8357         local mntpt=$(facet_mntpt mgs)
8358         local mgsdev=$(mgsdevname 1)
8359         local fid_list
8360         local fid
8361         local rec_list
8362         local rec
8363         local rec_type
8364         local obj_file
8365         local path
8366         local seq
8367         local oid
8368         local pass=true
8369
8370         #get fid and record list
8371         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8372                 tail -n 4))
8373         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8374                 tail -n 4))
8375         #remount mgs as ldiskfs or zfs type
8376         stop mgs || error "stop mgs failed"
8377         mount_fstype mgs || error "remount mgs failed"
8378         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8379                 fid=${fid_list[i]}
8380                 rec=${rec_list[i]}
8381                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8382                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8383                 oid=$((16#$oid))
8384
8385                 case $fstype in
8386                         ldiskfs )
8387                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8388                         zfs )
8389                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8390                 esac
8391                 echo "obj_file is $obj_file"
8392                 do_facet mgs $llog_reader $obj_file
8393
8394                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8395                         awk '{ print $3 }' | sed -e "s/^type=//g")
8396                 if [ $rec_type != $rec ]; then
8397                         echo "FAILED test_60a wrong record type $rec_type," \
8398                               "should be $rec"
8399                         pass=false
8400                         break
8401                 fi
8402
8403                 #check obj path if record type is LLOG_LOGID_MAGIC
8404                 if [ "$rec" == "1064553b" ]; then
8405                         path=$(do_facet mgs $llog_reader $obj_file |
8406                                 grep "path=" | awk '{ print $NF }' |
8407                                 sed -e "s/^path=//g")
8408                         if [ $obj_file != $mntpt/$path ]; then
8409                                 echo "FAILED test_60a wrong obj path" \
8410                                       "$montpt/$path, should be $obj_file"
8411                                 pass=false
8412                                 break
8413                         fi
8414                 fi
8415         done
8416         rm -f $TMP/$tfile
8417         #restart mgs before "error", otherwise it will block the next test
8418         stop mgs || error "stop mgs failed"
8419         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8420         $pass || error "test failed, see FAILED test_60a messages for specifics"
8421 }
8422 run_test 60a "llog_test run from kernel module and test llog_reader"
8423
8424 test_60b() { # bug 6411
8425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8426
8427         dmesg > $DIR/$tfile
8428         LLOG_COUNT=$(do_facet mgs dmesg |
8429                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8430                           /llog_[a-z]*.c:[0-9]/ {
8431                                 if (marker)
8432                                         from_marker++
8433                                 from_begin++
8434                           }
8435                           END {
8436                                 if (marker)
8437                                         print from_marker
8438                                 else
8439                                         print from_begin
8440                           }")
8441
8442         [[ $LLOG_COUNT -gt 120 ]] &&
8443                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8444 }
8445 run_test 60b "limit repeated messages from CERROR/CWARN"
8446
8447 test_60c() {
8448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8449
8450         echo "create 5000 files"
8451         createmany -o $DIR/f60c- 5000
8452 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8453         lctl set_param fail_loc=0x80000137
8454         unlinkmany $DIR/f60c- 5000
8455         lctl set_param fail_loc=0
8456 }
8457 run_test 60c "unlink file when mds full"
8458
8459 test_60d() {
8460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8461
8462         SAVEPRINTK=$(lctl get_param -n printk)
8463         # verify "lctl mark" is even working"
8464         MESSAGE="test message ID $RANDOM $$"
8465         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8466         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8467
8468         lctl set_param printk=0 || error "set lnet.printk failed"
8469         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8470         MESSAGE="new test message ID $RANDOM $$"
8471         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8472         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8473         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8474
8475         lctl set_param -n printk="$SAVEPRINTK"
8476 }
8477 run_test 60d "test printk console message masking"
8478
8479 test_60e() {
8480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8481         remote_mds_nodsh && skip "remote MDS with nodsh"
8482
8483         touch $DIR/$tfile
8484 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8485         do_facet mds1 lctl set_param fail_loc=0x15b
8486         rm $DIR/$tfile
8487 }
8488 run_test 60e "no space while new llog is being created"
8489
8490 test_60f() {
8491         local old_path=$($LCTL get_param -n debug_path)
8492
8493         stack_trap "$LCTL set_param debug_path=$old_path"
8494         stack_trap "rm -f $TMP/$tfile*"
8495         rm -f $TMP/$tfile* 2> /dev/null
8496         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8497         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8498         test_mkdir $DIR/$tdir
8499         # retry in case the open is cached and not released
8500         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8501                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8502                 sleep 0.1
8503         done
8504         ls $TMP/$tfile*
8505         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8506 }
8507 run_test 60f "change debug_path works"
8508
8509 test_60g() {
8510         local pid
8511         local i
8512
8513         test_mkdir -c $MDSCOUNT $DIR/$tdir
8514
8515         (
8516                 local index=0
8517                 while true; do
8518                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8519                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8520                                 2>/dev/null
8521                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8522                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8523                         index=$((index + 1))
8524                 done
8525         ) &
8526
8527         pid=$!
8528
8529         for i in {0..100}; do
8530                 # define OBD_FAIL_OSD_TXN_START    0x19a
8531                 local index=$((i % MDSCOUNT + 1))
8532
8533                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8534                         > /dev/null
8535                 sleep 0.01
8536         done
8537
8538         kill -9 $pid
8539
8540         for i in $(seq $MDSCOUNT); do
8541                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8542         done
8543
8544         mkdir $DIR/$tdir/new || error "mkdir failed"
8545         rmdir $DIR/$tdir/new || error "rmdir failed"
8546
8547         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8548                 -t namespace
8549         for i in $(seq $MDSCOUNT); do
8550                 wait_update_facet mds$i "$LCTL get_param -n \
8551                         mdd.$(facet_svc mds$i).lfsck_namespace |
8552                         awk '/^status/ { print \\\$2 }'" "completed"
8553         done
8554
8555         ls -R $DIR/$tdir
8556         rm -rf $DIR/$tdir || error "rmdir failed"
8557 }
8558 run_test 60g "transaction abort won't cause MDT hung"
8559
8560 test_60h() {
8561         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8562                 skip "Need MDS version at least 2.12.52"
8563         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8564
8565         local f
8566
8567         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8568         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8569         for fail_loc in 0x80000188 0x80000189; do
8570                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8571                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8572                         error "mkdir $dir-$fail_loc failed"
8573                 for i in {0..10}; do
8574                         # create may fail on missing stripe
8575                         echo $i > $DIR/$tdir-$fail_loc/$i
8576                 done
8577                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8578                         error "getdirstripe $tdir-$fail_loc failed"
8579                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8580                         error "migrate $tdir-$fail_loc failed"
8581                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8582                         error "getdirstripe $tdir-$fail_loc failed"
8583                 pushd $DIR/$tdir-$fail_loc
8584                 for f in *; do
8585                         echo $f | cmp $f - || error "$f data mismatch"
8586                 done
8587                 popd
8588                 rm -rf $DIR/$tdir-$fail_loc
8589         done
8590 }
8591 run_test 60h "striped directory with missing stripes can be accessed"
8592
8593 function t60i_load() {
8594         mkdir $DIR/$tdir
8595         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8596         $LCTL set_param fail_loc=0x131c fail_val=1
8597         for ((i=0; i<5000; i++)); do
8598                 touch $DIR/$tdir/f$i
8599         done
8600 }
8601
8602 test_60i() {
8603         changelog_register || error "changelog_register failed"
8604         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8605         changelog_users $SINGLEMDS | grep -q $cl_user ||
8606                 error "User $cl_user not found in changelog_users"
8607         changelog_chmask "ALL"
8608         t60i_load &
8609         local PID=$!
8610         for((i=0; i<100; i++)); do
8611                 changelog_dump >/dev/null ||
8612                         error "can't read changelog"
8613         done
8614         kill $PID
8615         wait $PID
8616         changelog_deregister || error "changelog_deregister failed"
8617         $LCTL set_param fail_loc=0
8618 }
8619 run_test 60i "llog: new record vs reader race"
8620
8621 test_61a() {
8622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8623
8624         f="$DIR/f61"
8625         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8626         cancel_lru_locks osc
8627         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8628         sync
8629 }
8630 run_test 61a "mmap() writes don't make sync hang ================"
8631
8632 test_61b() {
8633         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8634 }
8635 run_test 61b "mmap() of unstriped file is successful"
8636
8637 # bug 2330 - insufficient obd_match error checking causes LBUG
8638 test_62() {
8639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8640
8641         f="$DIR/f62"
8642         echo foo > $f
8643         cancel_lru_locks osc
8644         lctl set_param fail_loc=0x405
8645         cat $f && error "cat succeeded, expect -EIO"
8646         lctl set_param fail_loc=0
8647 }
8648 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8649 # match every page all of the time.
8650 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8651
8652 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8653 # Though this test is irrelevant anymore, it helped to reveal some
8654 # other grant bugs (LU-4482), let's keep it.
8655 test_63a() {   # was test_63
8656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8657
8658         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8659
8660         for i in `seq 10` ; do
8661                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8662                 sleep 5
8663                 kill $!
8664                 sleep 1
8665         done
8666
8667         rm -f $DIR/f63 || true
8668 }
8669 run_test 63a "Verify oig_wait interruption does not crash ======="
8670
8671 # bug 2248 - async write errors didn't return to application on sync
8672 # bug 3677 - async write errors left page locked
8673 test_63b() {
8674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8675
8676         debugsave
8677         lctl set_param debug=-1
8678
8679         # ensure we have a grant to do async writes
8680         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8681         rm $DIR/$tfile
8682
8683         sync    # sync lest earlier test intercept the fail_loc
8684
8685         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8686         lctl set_param fail_loc=0x80000406
8687         $MULTIOP $DIR/$tfile Owy && \
8688                 error "sync didn't return ENOMEM"
8689         sync; sleep 2; sync     # do a real sync this time to flush page
8690         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8691                 error "locked page left in cache after async error" || true
8692         debugrestore
8693 }
8694 run_test 63b "async write errors should be returned to fsync ==="
8695
8696 test_64a () {
8697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8698
8699         lfs df $DIR
8700         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8701 }
8702 run_test 64a "verify filter grant calculations (in kernel) ====="
8703
8704 test_64b () {
8705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8706
8707         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8708 }
8709 run_test 64b "check out-of-space detection on client"
8710
8711 test_64c() {
8712         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8713 }
8714 run_test 64c "verify grant shrink"
8715
8716 import_param() {
8717         local tgt=$1
8718         local param=$2
8719
8720         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8721 }
8722
8723 # this does exactly what osc_request.c:osc_announce_cached() does in
8724 # order to calculate max amount of grants to ask from server
8725 want_grant() {
8726         local tgt=$1
8727
8728         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8729         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8730
8731         ((rpc_in_flight++));
8732         nrpages=$((nrpages * rpc_in_flight))
8733
8734         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8735
8736         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8737
8738         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8739         local undirty=$((nrpages * PAGE_SIZE))
8740
8741         local max_extent_pages
8742         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8743         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8744         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8745         local grant_extent_tax
8746         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8747
8748         undirty=$((undirty + nrextents * grant_extent_tax))
8749
8750         echo $undirty
8751 }
8752
8753 # this is size of unit for grant allocation. It should be equal to
8754 # what tgt_grant.c:tgt_grant_chunk() calculates
8755 grant_chunk() {
8756         local tgt=$1
8757         local max_brw_size
8758         local grant_extent_tax
8759
8760         max_brw_size=$(import_param $tgt max_brw_size)
8761
8762         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8763
8764         echo $(((max_brw_size + grant_extent_tax) * 2))
8765 }
8766
8767 test_64d() {
8768         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8769                 skip "OST < 2.10.55 doesn't limit grants enough"
8770
8771         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8772
8773         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8774                 skip "no grant_param connect flag"
8775
8776         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8777
8778         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8779         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8780
8781
8782         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8783         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8784
8785         $LFS setstripe $DIR/$tfile -i 0 -c 1
8786         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8787         ddpid=$!
8788
8789         while kill -0 $ddpid; do
8790                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8791
8792                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8793                         kill $ddpid
8794                         error "cur_grant $cur_grant > $max_cur_granted"
8795                 fi
8796
8797                 sleep 1
8798         done
8799 }
8800 run_test 64d "check grant limit exceed"
8801
8802 check_grants() {
8803         local tgt=$1
8804         local expected=$2
8805         local msg=$3
8806         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8807
8808         ((cur_grants == expected)) ||
8809                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8810 }
8811
8812 round_up_p2() {
8813         echo $((($1 + $2 - 1) & ~($2 - 1)))
8814 }
8815
8816 test_64e() {
8817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8818         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8819                 skip "Need OSS version at least 2.11.56"
8820
8821         # Remount client to reset grant
8822         remount_client $MOUNT || error "failed to remount client"
8823         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8824
8825         local init_grants=$(import_param $osc_tgt initial_grant)
8826
8827         check_grants $osc_tgt $init_grants "init grants"
8828
8829         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8830         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8831         local gbs=$(import_param $osc_tgt grant_block_size)
8832
8833         # write random number of bytes from max_brw_size / 4 to max_brw_size
8834         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8835         # align for direct io
8836         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8837         # round to grant consumption unit
8838         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8839
8840         local grants=$((wb_round_up + extent_tax))
8841
8842         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8843
8844         # define OBD_FAIL_TGT_NO_GRANT 0x725
8845         # make the server not grant more back
8846         do_facet ost1 $LCTL set_param fail_loc=0x725
8847         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8848
8849         do_facet ost1 $LCTL set_param fail_loc=0
8850
8851         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8852
8853         rm -f $DIR/$tfile || error "rm failed"
8854
8855         # Remount client to reset grant
8856         remount_client $MOUNT || error "failed to remount client"
8857         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8858
8859         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8860
8861         # define OBD_FAIL_TGT_NO_GRANT 0x725
8862         # make the server not grant more back
8863         do_facet ost1 $LCTL set_param fail_loc=0x725
8864         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8865         do_facet ost1 $LCTL set_param fail_loc=0
8866
8867         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8868 }
8869 run_test 64e "check grant consumption (no grant allocation)"
8870
8871 test_64f() {
8872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8873
8874         # Remount client to reset grant
8875         remount_client $MOUNT || error "failed to remount client"
8876         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8877
8878         local init_grants=$(import_param $osc_tgt initial_grant)
8879         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8880         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8881         local gbs=$(import_param $osc_tgt grant_block_size)
8882         local chunk=$(grant_chunk $osc_tgt)
8883
8884         # write random number of bytes from max_brw_size / 4 to max_brw_size
8885         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8886         # align for direct io
8887         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8888         # round to grant consumption unit
8889         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8890
8891         local grants=$((wb_round_up + extent_tax))
8892
8893         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8894         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8895                 error "error writing to $DIR/$tfile"
8896
8897         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8898                 "direct io with grant allocation"
8899
8900         rm -f $DIR/$tfile || error "rm failed"
8901
8902         # Remount client to reset grant
8903         remount_client $MOUNT || error "failed to remount client"
8904         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8905
8906         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8907
8908         local cmd="oO_WRONLY:w${write_bytes}_yc"
8909
8910         $MULTIOP $DIR/$tfile $cmd &
8911         MULTIPID=$!
8912         sleep 1
8913
8914         check_grants $osc_tgt $((init_grants - grants)) \
8915                 "buffered io, not write rpc"
8916
8917         kill -USR1 $MULTIPID
8918         wait
8919
8920         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8921                 "buffered io, one RPC"
8922 }
8923 run_test 64f "check grant consumption (with grant allocation)"
8924
8925 test_64g() {
8926         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
8927                 skip "Need MDS version at least 2.14.56"
8928
8929         local mdts=$(comma_list $(mdts_nodes))
8930
8931         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8932                         tr '\n' ' ')
8933         stack_trap "$LCTL set_param $old"
8934
8935         # generate dirty pages and increase dirty granted on MDT
8936         stack_trap "rm -f $DIR/$tfile-*"
8937         for (( i = 0; i < 10; i++)); do
8938                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8939                         error "can't set stripe"
8940                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8941                         error "can't dd"
8942                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8943                         $LFS getstripe $DIR/$tfile-$i
8944                         error "not DoM file"
8945                 }
8946         done
8947
8948         # flush dirty pages
8949         sync
8950
8951         # wait until grant shrink reset grant dirty on MDTs
8952         for ((i = 0; i < 120; i++)); do
8953                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8954                         awk '{sum=sum+$1} END {print sum}')
8955                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8956                 echo "$grant_dirty grants, $vm_dirty pages"
8957                 (( grant_dirty + vm_dirty == 0 )) && break
8958                 (( i == 3 )) && sync &&
8959                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8960                 sleep 1
8961         done
8962
8963         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8964                 awk '{sum=sum+$1} END {print sum}')
8965         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8966 }
8967 run_test 64g "grant shrink on MDT"
8968
8969 test_64h() {
8970         local instance=$($LFS getname -i $DIR)
8971         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8972         local num_exps=$(do_facet ost1 \
8973             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8974         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8975         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8976         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8977
8978         # 10MiB is for file to be written, max_brw_size * 16 *
8979         # num_exps is space reserve so that tgt_grant_shrink() decided
8980         # to not shrink
8981         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8982         (( avail * 1024 < expect )) &&
8983                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8984
8985         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8986         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8987         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8988         $LCTL set_param osc.*OST0000*.grant_shrink=1
8989         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8990
8991         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8992         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8993
8994         # drop cache so that coming read would do rpc
8995         cancel_lru_locks osc
8996
8997         # shrink interval is set to 10, pause for 7 seconds so that
8998         # grant thread did not wake up yet but coming read entered
8999         # shrink mode for rpc (osc_should_shrink_grant())
9000         sleep 7
9001
9002         declare -a cur_grant_bytes
9003         declare -a tot_granted
9004         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9005         tot_granted[0]=$(do_facet ost1 \
9006             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9007
9008         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9009
9010         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9011         tot_granted[1]=$(do_facet ost1 \
9012             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9013
9014         # grant change should be equal on both sides
9015         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9016                 tot_granted[0] - tot_granted[1])) ||
9017                 error "grant change mismatch, "                                \
9018                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9019                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9020 }
9021 run_test 64h "grant shrink on read"
9022
9023 test_64i() {
9024         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
9025                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
9026
9027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9028         remote_ost_nodsh && skip "remote OSTs with nodsh"
9029
9030         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9031
9032         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9033
9034         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9035         local instance=$($LFS getname -i $DIR)
9036
9037         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9038         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9039
9040         # shrink grants and simulate rpc loss
9041         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9042         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9043         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9044
9045         fail ost1
9046
9047         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9048
9049         local testid=$(echo $TESTNAME | tr '_' ' ')
9050
9051         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9052                 grep "GRANT, real grant" &&
9053                 error "client has more grants then it owns" || true
9054 }
9055 run_test 64i "shrink on reconnect"
9056
9057 # bug 1414 - set/get directories' stripe info
9058 test_65a() {
9059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9060
9061         test_mkdir $DIR/$tdir
9062         touch $DIR/$tdir/f1
9063         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9064 }
9065 run_test 65a "directory with no stripe info"
9066
9067 test_65b() {
9068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9069
9070         test_mkdir $DIR/$tdir
9071         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9072
9073         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9074                                                 error "setstripe"
9075         touch $DIR/$tdir/f2
9076         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9077 }
9078 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9079
9080 test_65c() {
9081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9082         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9083
9084         test_mkdir $DIR/$tdir
9085         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9086
9087         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9088                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9089         touch $DIR/$tdir/f3
9090         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9091 }
9092 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9093
9094 test_65d() {
9095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9096
9097         test_mkdir $DIR/$tdir
9098         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9099         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9100
9101         if [[ $STRIPECOUNT -le 0 ]]; then
9102                 sc=1
9103         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9104                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9105                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9106         else
9107                 sc=$(($STRIPECOUNT - 1))
9108         fi
9109         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9110         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9111         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9112                 error "lverify failed"
9113 }
9114 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9115
9116 test_65e() {
9117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9118
9119         test_mkdir $DIR/$tdir
9120
9121         $LFS setstripe $DIR/$tdir || error "setstripe"
9122         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9123                                         error "no stripe info failed"
9124         touch $DIR/$tdir/f6
9125         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9126 }
9127 run_test 65e "directory setstripe defaults"
9128
9129 test_65f() {
9130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9131
9132         test_mkdir $DIR/${tdir}f
9133         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9134                 error "setstripe succeeded" || true
9135 }
9136 run_test 65f "dir setstripe permission (should return error) ==="
9137
9138 test_65g() {
9139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9140
9141         test_mkdir $DIR/$tdir
9142         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9143
9144         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9145                 error "setstripe -S failed"
9146         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9147         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9148                 error "delete default stripe failed"
9149 }
9150 run_test 65g "directory setstripe -d"
9151
9152 test_65h() {
9153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9154
9155         test_mkdir $DIR/$tdir
9156         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9157
9158         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9159                 error "setstripe -S failed"
9160         test_mkdir $DIR/$tdir/dd1
9161         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9162                 error "stripe info inherit failed"
9163 }
9164 run_test 65h "directory stripe info inherit ===================="
9165
9166 test_65i() {
9167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9168
9169         save_layout_restore_at_exit $MOUNT
9170
9171         # bug6367: set non-default striping on root directory
9172         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9173
9174         # bug12836: getstripe on -1 default directory striping
9175         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9176
9177         # bug12836: getstripe -v on -1 default directory striping
9178         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9179
9180         # bug12836: new find on -1 default directory striping
9181         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9182 }
9183 run_test 65i "various tests to set root directory striping"
9184
9185 test_65j() { # bug6367
9186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9187
9188         sync; sleep 1
9189
9190         # if we aren't already remounting for each test, do so for this test
9191         if [ "$I_MOUNTED" = "yes" ]; then
9192                 cleanup || error "failed to unmount"
9193                 setup
9194         fi
9195
9196         save_layout_restore_at_exit $MOUNT
9197
9198         $LFS setstripe -d $MOUNT || error "setstripe failed"
9199 }
9200 run_test 65j "set default striping on root directory (bug 6367)="
9201
9202 cleanup_65k() {
9203         rm -rf $DIR/$tdir
9204         wait_delete_completed
9205         do_facet $SINGLEMDS "lctl set_param -n \
9206                 osp.$ost*MDT0000.max_create_count=$max_count"
9207         do_facet $SINGLEMDS "lctl set_param -n \
9208                 osp.$ost*MDT0000.create_count=$count"
9209         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9210         echo $INACTIVE_OSC "is Activate"
9211
9212         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9213 }
9214
9215 test_65k() { # bug11679
9216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9217         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9218         remote_mds_nodsh && skip "remote MDS with nodsh"
9219
9220         local disable_precreate=true
9221         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9222                 disable_precreate=false
9223
9224         echo "Check OST status: "
9225         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9226                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9227
9228         for OSC in $MDS_OSCS; do
9229                 echo $OSC "is active"
9230                 do_facet $SINGLEMDS lctl --device %$OSC activate
9231         done
9232
9233         for INACTIVE_OSC in $MDS_OSCS; do
9234                 local ost=$(osc_to_ost $INACTIVE_OSC)
9235                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9236                                lov.*md*.target_obd |
9237                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9238
9239                 mkdir -p $DIR/$tdir
9240                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9241                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9242
9243                 echo "Deactivate: " $INACTIVE_OSC
9244                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9245
9246                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9247                               osp.$ost*MDT0000.create_count")
9248                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9249                                   osp.$ost*MDT0000.max_create_count")
9250                 $disable_precreate &&
9251                         do_facet $SINGLEMDS "lctl set_param -n \
9252                                 osp.$ost*MDT0000.max_create_count=0"
9253
9254                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9255                         [ -f $DIR/$tdir/$idx ] && continue
9256                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9257                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9258                                 { cleanup_65k;
9259                                   error "setstripe $idx should succeed"; }
9260                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9261                 done
9262                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9263                 rmdir $DIR/$tdir
9264
9265                 do_facet $SINGLEMDS "lctl set_param -n \
9266                         osp.$ost*MDT0000.max_create_count=$max_count"
9267                 do_facet $SINGLEMDS "lctl set_param -n \
9268                         osp.$ost*MDT0000.create_count=$count"
9269                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9270                 echo $INACTIVE_OSC "is Activate"
9271
9272                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9273         done
9274 }
9275 run_test 65k "validate manual striping works properly with deactivated OSCs"
9276
9277 test_65l() { # bug 12836
9278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9279
9280         test_mkdir -p $DIR/$tdir/test_dir
9281         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9282         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9283 }
9284 run_test 65l "lfs find on -1 stripe dir ========================"
9285
9286 test_65m() {
9287         local layout=$(save_layout $MOUNT)
9288         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9289                 restore_layout $MOUNT $layout
9290                 error "setstripe should fail by non-root users"
9291         }
9292         true
9293 }
9294 run_test 65m "normal user can't set filesystem default stripe"
9295
9296 test_65n() {
9297         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9298         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9299                 skip "Need MDS version at least 2.12.50"
9300         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9301
9302         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9303         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9304         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9305
9306         save_layout_restore_at_exit $MOUNT
9307
9308         # new subdirectory under root directory should not inherit
9309         # the default layout from root
9310         local dir1=$MOUNT/$tdir-1
9311         mkdir $dir1 || error "mkdir $dir1 failed"
9312         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9313                 error "$dir1 shouldn't have LOV EA"
9314
9315         # delete the default layout on root directory
9316         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9317
9318         local dir2=$MOUNT/$tdir-2
9319         mkdir $dir2 || error "mkdir $dir2 failed"
9320         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9321                 error "$dir2 shouldn't have LOV EA"
9322
9323         # set a new striping pattern on root directory
9324         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9325         local new_def_stripe_size=$((def_stripe_size * 2))
9326         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9327                 error "set stripe size on $MOUNT failed"
9328
9329         # new file created in $dir2 should inherit the new stripe size from
9330         # the filesystem default
9331         local file2=$dir2/$tfile-2
9332         touch $file2 || error "touch $file2 failed"
9333
9334         local file2_stripe_size=$($LFS getstripe -S $file2)
9335         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9336         {
9337                 echo "file2_stripe_size: '$file2_stripe_size'"
9338                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9339                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9340         }
9341
9342         local dir3=$MOUNT/$tdir-3
9343         mkdir $dir3 || error "mkdir $dir3 failed"
9344         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9345         # the root layout, which is the actual default layout that will be used
9346         # when new files are created in $dir3.
9347         local dir3_layout=$(get_layout_param $dir3)
9348         local root_dir_layout=$(get_layout_param $MOUNT)
9349         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9350         {
9351                 echo "dir3_layout: '$dir3_layout'"
9352                 echo "root_dir_layout: '$root_dir_layout'"
9353                 error "$dir3 should show the default layout from $MOUNT"
9354         }
9355
9356         # set OST pool on root directory
9357         local pool=$TESTNAME
9358         pool_add $pool || error "add $pool failed"
9359         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9360                 error "add targets to $pool failed"
9361
9362         $LFS setstripe -p $pool $MOUNT ||
9363                 error "set OST pool on $MOUNT failed"
9364
9365         # new file created in $dir3 should inherit the pool from
9366         # the filesystem default
9367         local file3=$dir3/$tfile-3
9368         touch $file3 || error "touch $file3 failed"
9369
9370         local file3_pool=$($LFS getstripe -p $file3)
9371         [[ "$file3_pool" = "$pool" ]] ||
9372                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9373
9374         local dir4=$MOUNT/$tdir-4
9375         mkdir $dir4 || error "mkdir $dir4 failed"
9376         local dir4_layout=$(get_layout_param $dir4)
9377         root_dir_layout=$(get_layout_param $MOUNT)
9378         echo "$LFS getstripe -d $dir4"
9379         $LFS getstripe -d $dir4
9380         echo "$LFS getstripe -d $MOUNT"
9381         $LFS getstripe -d $MOUNT
9382         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9383         {
9384                 echo "dir4_layout: '$dir4_layout'"
9385                 echo "root_dir_layout: '$root_dir_layout'"
9386                 error "$dir4 should show the default layout from $MOUNT"
9387         }
9388
9389         # new file created in $dir4 should inherit the pool from
9390         # the filesystem default
9391         local file4=$dir4/$tfile-4
9392         touch $file4 || error "touch $file4 failed"
9393
9394         local file4_pool=$($LFS getstripe -p $file4)
9395         [[ "$file4_pool" = "$pool" ]] ||
9396                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9397
9398         # new subdirectory under non-root directory should inherit
9399         # the default layout from its parent directory
9400         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9401                 error "set directory layout on $dir4 failed"
9402
9403         local dir5=$dir4/$tdir-5
9404         mkdir $dir5 || error "mkdir $dir5 failed"
9405
9406         dir4_layout=$(get_layout_param $dir4)
9407         local dir5_layout=$(get_layout_param $dir5)
9408         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9409         {
9410                 echo "dir4_layout: '$dir4_layout'"
9411                 echo "dir5_layout: '$dir5_layout'"
9412                 error "$dir5 should inherit the default layout from $dir4"
9413         }
9414
9415         # though subdir under ROOT doesn't inherit default layout, but
9416         # its sub dir/file should be created with default layout.
9417         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9418         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9419                 skip "Need MDS version at least 2.12.59"
9420
9421         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9422         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9423         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9424
9425         if [ $default_lmv_hash == "none" ]; then
9426                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9427         else
9428                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9429                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9430         fi
9431
9432         $LFS setdirstripe -D -c 2 $MOUNT ||
9433                 error "setdirstripe -D -c 2 failed"
9434         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9435         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9436         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9437
9438         # $dir4 layout includes pool
9439         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9440         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9441                 error "pool lost on setstripe"
9442         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9443         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9444                 error "pool lost on compound layout setstripe"
9445 }
9446 run_test 65n "don't inherit default layout from root for new subdirectories"
9447
9448 # bug 2543 - update blocks count on client
9449 test_66() {
9450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9451
9452         COUNT=${COUNT:-8}
9453         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9454         sync; sync_all_data; sync; sync_all_data
9455         cancel_lru_locks osc
9456         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9457         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9458 }
9459 run_test 66 "update inode blocks count on client ==============="
9460
9461 meminfo() {
9462         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9463 }
9464
9465 swap_used() {
9466         swapon -s | awk '($1 == "'$1'") { print $4 }'
9467 }
9468
9469 # bug5265, obdfilter oa2dentry return -ENOENT
9470 # #define OBD_FAIL_SRV_ENOENT 0x217
9471 test_69() {
9472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9473         remote_ost_nodsh && skip "remote OST with nodsh"
9474
9475         f="$DIR/$tfile"
9476         $LFS setstripe -c 1 -i 0 $f
9477
9478         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9479
9480         do_facet ost1 lctl set_param fail_loc=0x217
9481         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9482         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9483
9484         do_facet ost1 lctl set_param fail_loc=0
9485         $DIRECTIO write $f 0 2 || error "write error"
9486
9487         cancel_lru_locks osc
9488         $DIRECTIO read $f 0 1 || error "read error"
9489
9490         do_facet ost1 lctl set_param fail_loc=0x217
9491         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9492
9493         do_facet ost1 lctl set_param fail_loc=0
9494         rm -f $f
9495 }
9496 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9497
9498 test_71() {
9499         test_mkdir $DIR/$tdir
9500         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9501         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9502 }
9503 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9504
9505 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9507         [ "$RUNAS_ID" = "$UID" ] &&
9508                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9509         # Check that testing environment is properly set up. Skip if not
9510         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9511                 skip_env "User $RUNAS_ID does not exist - skipping"
9512
9513         touch $DIR/$tfile
9514         chmod 777 $DIR/$tfile
9515         chmod ug+s $DIR/$tfile
9516         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9517                 error "$RUNAS dd $DIR/$tfile failed"
9518         # See if we are still setuid/sgid
9519         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9520                 error "S/gid is not dropped on write"
9521         # Now test that MDS is updated too
9522         cancel_lru_locks mdc
9523         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9524                 error "S/gid is not dropped on MDS"
9525         rm -f $DIR/$tfile
9526 }
9527 run_test 72a "Test that remove suid works properly (bug5695) ===="
9528
9529 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9530         local perm
9531
9532         [ "$RUNAS_ID" = "$UID" ] &&
9533                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9534         [ "$RUNAS_ID" -eq 0 ] &&
9535                 skip_env "RUNAS_ID = 0 -- skipping"
9536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9537         # Check that testing environment is properly set up. Skip if not
9538         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9539                 skip_env "User $RUNAS_ID does not exist - skipping"
9540
9541         touch $DIR/${tfile}-f{g,u}
9542         test_mkdir $DIR/${tfile}-dg
9543         test_mkdir $DIR/${tfile}-du
9544         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9545         chmod g+s $DIR/${tfile}-{f,d}g
9546         chmod u+s $DIR/${tfile}-{f,d}u
9547         for perm in 777 2777 4777; do
9548                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9549                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9550                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9551                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9552         done
9553         true
9554 }
9555 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9556
9557 # bug 3462 - multiple simultaneous MDC requests
9558 test_73() {
9559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9560
9561         test_mkdir $DIR/d73-1
9562         test_mkdir $DIR/d73-2
9563         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9564         pid1=$!
9565
9566         lctl set_param fail_loc=0x80000129
9567         $MULTIOP $DIR/d73-1/f73-2 Oc &
9568         sleep 1
9569         lctl set_param fail_loc=0
9570
9571         $MULTIOP $DIR/d73-2/f73-3 Oc &
9572         pid3=$!
9573
9574         kill -USR1 $pid1
9575         wait $pid1 || return 1
9576
9577         sleep 25
9578
9579         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9580         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9581         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9582
9583         rm -rf $DIR/d73-*
9584 }
9585 run_test 73 "multiple MDC requests (should not deadlock)"
9586
9587 test_74a() { # bug 6149, 6184
9588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9589
9590         touch $DIR/f74a
9591         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9592         #
9593         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9594         # will spin in a tight reconnection loop
9595         $LCTL set_param fail_loc=0x8000030e
9596         # get any lock that won't be difficult - lookup works.
9597         ls $DIR/f74a
9598         $LCTL set_param fail_loc=0
9599         rm -f $DIR/f74a
9600         true
9601 }
9602 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9603
9604 test_74b() { # bug 13310
9605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9606
9607         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9608         #
9609         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9610         # will spin in a tight reconnection loop
9611         $LCTL set_param fail_loc=0x8000030e
9612         # get a "difficult" lock
9613         touch $DIR/f74b
9614         $LCTL set_param fail_loc=0
9615         rm -f $DIR/f74b
9616         true
9617 }
9618 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9619
9620 test_74c() {
9621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9622
9623         #define OBD_FAIL_LDLM_NEW_LOCK
9624         $LCTL set_param fail_loc=0x319
9625         touch $DIR/$tfile && error "touch successful"
9626         $LCTL set_param fail_loc=0
9627         true
9628 }
9629 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9630
9631 slab_lic=/sys/kernel/slab/lustre_inode_cache
9632 num_objects() {
9633         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9634         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9635                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9636 }
9637
9638 test_76a() { # Now for b=20433, added originally in b=1443
9639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9640
9641         cancel_lru_locks osc
9642         # there may be some slab objects cached per core
9643         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9644         local before=$(num_objects)
9645         local count=$((512 * cpus))
9646         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9647         local margin=$((count / 10))
9648         if [[ -f $slab_lic/aliases ]]; then
9649                 local aliases=$(cat $slab_lic/aliases)
9650                 (( aliases > 0 )) && margin=$((margin * aliases))
9651         fi
9652
9653         echo "before slab objects: $before"
9654         for i in $(seq $count); do
9655                 touch $DIR/$tfile
9656                 rm -f $DIR/$tfile
9657         done
9658         cancel_lru_locks osc
9659         local after=$(num_objects)
9660         echo "created: $count, after slab objects: $after"
9661         # shared slab counts are not very accurate, allow significant margin
9662         # the main goal is that the cache growth is not permanently > $count
9663         while (( after > before + margin )); do
9664                 sleep 1
9665                 after=$(num_objects)
9666                 wait=$((wait + 1))
9667                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9668                 if (( wait > 60 )); then
9669                         error "inode slab grew from $before+$margin to $after"
9670                 fi
9671         done
9672 }
9673 run_test 76a "confirm clients recycle inodes properly ===="
9674
9675 test_76b() {
9676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9677         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9678
9679         local count=512
9680         local before=$(num_objects)
9681
9682         for i in $(seq $count); do
9683                 mkdir $DIR/$tdir
9684                 rmdir $DIR/$tdir
9685         done
9686
9687         local after=$(num_objects)
9688         local wait=0
9689
9690         while (( after > before )); do
9691                 sleep 1
9692                 after=$(num_objects)
9693                 wait=$((wait + 1))
9694                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9695                 if (( wait > 60 )); then
9696                         error "inode slab grew from $before to $after"
9697                 fi
9698         done
9699
9700         echo "slab objects before: $before, after: $after"
9701 }
9702 run_test 76b "confirm clients recycle directory inodes properly ===="
9703
9704 export ORIG_CSUM=""
9705 set_checksums()
9706 {
9707         # Note: in sptlrpc modes which enable its own bulk checksum, the
9708         # original crc32_le bulk checksum will be automatically disabled,
9709         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9710         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9711         # In this case set_checksums() will not be no-op, because sptlrpc
9712         # bulk checksum will be enabled all through the test.
9713
9714         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9715         lctl set_param -n osc.*.checksums $1
9716         return 0
9717 }
9718
9719 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9720                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9721 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9722                              tr -d [] | head -n1)}
9723 set_checksum_type()
9724 {
9725         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9726         rc=$?
9727         log "set checksum type to $1, rc = $rc"
9728         return $rc
9729 }
9730
9731 get_osc_checksum_type()
9732 {
9733         # arugment 1: OST name, like OST0000
9734         ost=$1
9735         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9736                         sed 's/.*\[\(.*\)\].*/\1/g')
9737         rc=$?
9738         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9739         echo $checksum_type
9740 }
9741
9742 F77_TMP=$TMP/f77-temp
9743 F77SZ=8
9744 setup_f77() {
9745         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9746                 error "error writing to $F77_TMP"
9747 }
9748
9749 test_77a() { # bug 10889
9750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9751         $GSS && skip_env "could not run with gss"
9752
9753         [ ! -f $F77_TMP ] && setup_f77
9754         set_checksums 1
9755         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9756         set_checksums 0
9757         rm -f $DIR/$tfile
9758 }
9759 run_test 77a "normal checksum read/write operation"
9760
9761 test_77b() { # bug 10889
9762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9763         $GSS && skip_env "could not run with gss"
9764
9765         [ ! -f $F77_TMP ] && setup_f77
9766         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9767         $LCTL set_param fail_loc=0x80000409
9768         set_checksums 1
9769
9770         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9771                 error "dd error: $?"
9772         $LCTL set_param fail_loc=0
9773
9774         for algo in $CKSUM_TYPES; do
9775                 cancel_lru_locks osc
9776                 set_checksum_type $algo
9777                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9778                 $LCTL set_param fail_loc=0x80000408
9779                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9780                 $LCTL set_param fail_loc=0
9781         done
9782         set_checksums 0
9783         set_checksum_type $ORIG_CSUM_TYPE
9784         rm -f $DIR/$tfile
9785 }
9786 run_test 77b "checksum error on client write, read"
9787
9788 cleanup_77c() {
9789         trap 0
9790         set_checksums 0
9791         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9792         $check_ost &&
9793                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9794         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9795         $check_ost && [ -n "$ost_file_prefix" ] &&
9796                 do_facet ost1 rm -f ${ost_file_prefix}\*
9797 }
9798
9799 test_77c() {
9800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9801         $GSS && skip_env "could not run with gss"
9802         remote_ost_nodsh && skip "remote OST with nodsh"
9803
9804         local bad1
9805         local osc_file_prefix
9806         local osc_file
9807         local check_ost=false
9808         local ost_file_prefix
9809         local ost_file
9810         local orig_cksum
9811         local dump_cksum
9812         local fid
9813
9814         # ensure corruption will occur on first OSS/OST
9815         $LFS setstripe -i 0 $DIR/$tfile
9816
9817         [ ! -f $F77_TMP ] && setup_f77
9818         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9819                 error "dd write error: $?"
9820         fid=$($LFS path2fid $DIR/$tfile)
9821
9822         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9823         then
9824                 check_ost=true
9825                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9826                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9827         else
9828                 echo "OSS do not support bulk pages dump upon error"
9829         fi
9830
9831         osc_file_prefix=$($LCTL get_param -n debug_path)
9832         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9833
9834         trap cleanup_77c EXIT
9835
9836         set_checksums 1
9837         # enable bulk pages dump upon error on Client
9838         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9839         # enable bulk pages dump upon error on OSS
9840         $check_ost &&
9841                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9842
9843         # flush Client cache to allow next read to reach OSS
9844         cancel_lru_locks osc
9845
9846         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9847         $LCTL set_param fail_loc=0x80000408
9848         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9849         $LCTL set_param fail_loc=0
9850
9851         rm -f $DIR/$tfile
9852
9853         # check cksum dump on Client
9854         osc_file=$(ls ${osc_file_prefix}*)
9855         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9856         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9857         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9858         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9859         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9860                      cksum)
9861         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9862         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9863                 error "dump content does not match on Client"
9864
9865         $check_ost || skip "No need to check cksum dump on OSS"
9866
9867         # check cksum dump on OSS
9868         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9869         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9870         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9871         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9872         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9873                 error "dump content does not match on OSS"
9874
9875         cleanup_77c
9876 }
9877 run_test 77c "checksum error on client read with debug"
9878
9879 test_77d() { # bug 10889
9880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9881         $GSS && skip_env "could not run with gss"
9882
9883         stack_trap "rm -f $DIR/$tfile"
9884         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9885         $LCTL set_param fail_loc=0x80000409
9886         set_checksums 1
9887         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9888                 error "direct write: rc=$?"
9889         $LCTL set_param fail_loc=0
9890         set_checksums 0
9891
9892         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9893         $LCTL set_param fail_loc=0x80000408
9894         set_checksums 1
9895         cancel_lru_locks osc
9896         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9897                 error "direct read: rc=$?"
9898         $LCTL set_param fail_loc=0
9899         set_checksums 0
9900 }
9901 run_test 77d "checksum error on OST direct write, read"
9902
9903 test_77f() { # bug 10889
9904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9905         $GSS && skip_env "could not run with gss"
9906
9907         set_checksums 1
9908         stack_trap "rm -f $DIR/$tfile"
9909         for algo in $CKSUM_TYPES; do
9910                 cancel_lru_locks osc
9911                 set_checksum_type $algo
9912                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9913                 $LCTL set_param fail_loc=0x409
9914                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9915                         error "direct write succeeded"
9916                 $LCTL set_param fail_loc=0
9917         done
9918         set_checksum_type $ORIG_CSUM_TYPE
9919         set_checksums 0
9920 }
9921 run_test 77f "repeat checksum error on write (expect error)"
9922
9923 test_77g() { # bug 10889
9924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9925         $GSS && skip_env "could not run with gss"
9926         remote_ost_nodsh && skip "remote OST with nodsh"
9927
9928         [ ! -f $F77_TMP ] && setup_f77
9929
9930         local file=$DIR/$tfile
9931         stack_trap "rm -f $file" EXIT
9932
9933         $LFS setstripe -c 1 -i 0 $file
9934         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9935         do_facet ost1 lctl set_param fail_loc=0x8000021a
9936         set_checksums 1
9937         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9938                 error "write error: rc=$?"
9939         do_facet ost1 lctl set_param fail_loc=0
9940         set_checksums 0
9941
9942         cancel_lru_locks osc
9943         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9944         do_facet ost1 lctl set_param fail_loc=0x8000021b
9945         set_checksums 1
9946         cmp $F77_TMP $file || error "file compare failed"
9947         do_facet ost1 lctl set_param fail_loc=0
9948         set_checksums 0
9949 }
9950 run_test 77g "checksum error on OST write, read"
9951
9952 test_77k() { # LU-10906
9953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9954         $GSS && skip_env "could not run with gss"
9955
9956         local cksum_param="osc.$FSNAME*.checksums"
9957         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9958         local checksum
9959         local i
9960
9961         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9962         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9963         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9964
9965         for i in 0 1; do
9966                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9967                         error "failed to set checksum=$i on MGS"
9968                 wait_update $HOSTNAME "$get_checksum" $i
9969                 #remount
9970                 echo "remount client, checksum should be $i"
9971                 remount_client $MOUNT || error "failed to remount client"
9972                 checksum=$(eval $get_checksum)
9973                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9974         done
9975         # remove persistent param to avoid races with checksum mountopt below
9976         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9977                 error "failed to delete checksum on MGS"
9978
9979         for opt in "checksum" "nochecksum"; do
9980                 #remount with mount option
9981                 echo "remount client with option $opt, checksum should be $i"
9982                 umount_client $MOUNT || error "failed to umount client"
9983                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9984                         error "failed to mount client with option '$opt'"
9985                 checksum=$(eval $get_checksum)
9986                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9987                 i=$((i - 1))
9988         done
9989
9990         remount_client $MOUNT || error "failed to remount client"
9991 }
9992 run_test 77k "enable/disable checksum correctly"
9993
9994 test_77l() {
9995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9996         $GSS && skip_env "could not run with gss"
9997
9998         set_checksums 1
9999         stack_trap "set_checksums $ORIG_CSUM" EXIT
10000         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10001
10002         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10003
10004         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10005         for algo in $CKSUM_TYPES; do
10006                 set_checksum_type $algo || error "fail to set checksum type $algo"
10007                 osc_algo=$(get_osc_checksum_type OST0000)
10008                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10009
10010                 # no locks, no reqs to let the connection idle
10011                 cancel_lru_locks osc
10012                 lru_resize_disable osc
10013                 wait_osc_import_state client ost1 IDLE
10014
10015                 # ensure ost1 is connected
10016                 stat $DIR/$tfile >/dev/null || error "can't stat"
10017                 wait_osc_import_state client ost1 FULL
10018
10019                 osc_algo=$(get_osc_checksum_type OST0000)
10020                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10021         done
10022         return 0
10023 }
10024 run_test 77l "preferred checksum type is remembered after reconnected"
10025
10026 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10027 rm -f $F77_TMP
10028 unset F77_TMP
10029
10030 test_77m() {
10031         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10032                 skip "Need at least version 2.14.52"
10033         local param=checksum_speed
10034
10035         $LCTL get_param $param || error "reading $param failed"
10036
10037         csum_speeds=$($LCTL get_param -n $param)
10038
10039         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10040                 error "known checksum types are missing"
10041 }
10042 run_test 77m "Verify checksum_speed is correctly read"
10043
10044 check_filefrag_77n() {
10045         local nr_ext=0
10046         local starts=()
10047         local ends=()
10048
10049         while read extidx a b start end rest; do
10050                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10051                         nr_ext=$(( $nr_ext + 1 ))
10052                         starts+=( ${start%..} )
10053                         ends+=( ${end%:} )
10054                 fi
10055         done < <( filefrag -sv $1 )
10056
10057         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10058         return 1
10059 }
10060
10061 test_77n() {
10062         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10063
10064         touch $DIR/$tfile
10065         $TRUNCATE $DIR/$tfile 0
10066         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10067         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10068         check_filefrag_77n $DIR/$tfile ||
10069                 skip "$tfile blocks not contiguous around hole"
10070
10071         set_checksums 1
10072         stack_trap "set_checksums $ORIG_CSUM" EXIT
10073         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10074         stack_trap "rm -f $DIR/$tfile"
10075
10076         for algo in $CKSUM_TYPES; do
10077                 if [[ "$algo" =~ ^t10 ]]; then
10078                         set_checksum_type $algo ||
10079                                 error "fail to set checksum type $algo"
10080                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10081                                 error "fail to read $tfile with $algo"
10082                 fi
10083         done
10084         rm -f $DIR/$tfile
10085         return 0
10086 }
10087 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10088
10089 test_77o() {
10090         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10091                 skip "Need MDS version at least 2.14.55"
10092         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10093                 skip "Need OST version at least 2.14.55"
10094         local ofd=obdfilter
10095         local mdt=mdt
10096
10097         # print OST checksum_type
10098         echo "$ofd.$FSNAME-*.checksum_type:"
10099         do_nodes $(comma_list $(osts_nodes)) \
10100                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10101
10102         # print MDT checksum_type
10103         echo "$mdt.$FSNAME-*.checksum_type:"
10104         do_nodes $(comma_list $(mdts_nodes)) \
10105                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10106
10107         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10108                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10109
10110         (( $o_count == $OSTCOUNT )) ||
10111                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10112
10113         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10114                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10115
10116         (( $m_count == $MDSCOUNT )) ||
10117                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10118 }
10119 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10120
10121 cleanup_test_78() {
10122         trap 0
10123         rm -f $DIR/$tfile
10124 }
10125
10126 test_78() { # bug 10901
10127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10128         remote_ost || skip_env "local OST"
10129
10130         NSEQ=5
10131         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10132         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10133         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10134         echo "MemTotal: $MEMTOTAL"
10135
10136         # reserve 256MB of memory for the kernel and other running processes,
10137         # and then take 1/2 of the remaining memory for the read/write buffers.
10138         if [ $MEMTOTAL -gt 512 ] ;then
10139                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10140         else
10141                 # for those poor memory-starved high-end clusters...
10142                 MEMTOTAL=$((MEMTOTAL / 2))
10143         fi
10144         echo "Mem to use for directio: $MEMTOTAL"
10145
10146         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10147         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10148         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10149         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10150                 head -n1)
10151         echo "Smallest OST: $SMALLESTOST"
10152         [[ $SMALLESTOST -lt 10240 ]] &&
10153                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10154
10155         trap cleanup_test_78 EXIT
10156
10157         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10158                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10159
10160         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10161         echo "File size: $F78SIZE"
10162         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10163         for i in $(seq 1 $NSEQ); do
10164                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10165                 echo directIO rdwr round $i of $NSEQ
10166                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10167         done
10168
10169         cleanup_test_78
10170 }
10171 run_test 78 "handle large O_DIRECT writes correctly ============"
10172
10173 test_79() { # bug 12743
10174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10175
10176         wait_delete_completed
10177
10178         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10179         BKFREE=$(calc_osc_kbytes kbytesfree)
10180         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10181
10182         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10183         DFTOTAL=`echo $STRING | cut -d, -f1`
10184         DFUSED=`echo $STRING  | cut -d, -f2`
10185         DFAVAIL=`echo $STRING | cut -d, -f3`
10186         DFFREE=$(($DFTOTAL - $DFUSED))
10187
10188         ALLOWANCE=$((64 * $OSTCOUNT))
10189
10190         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10191            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10192                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10193         fi
10194         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10195            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10196                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10197         fi
10198         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10199            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10200                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10201         fi
10202 }
10203 run_test 79 "df report consistency check ======================="
10204
10205 test_80() { # bug 10718
10206         remote_ost_nodsh && skip "remote OST with nodsh"
10207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10208
10209         # relax strong synchronous semantics for slow backends like ZFS
10210         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10211                 local soc="obdfilter.*.sync_lock_cancel"
10212                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10213
10214                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10215                 if [ -z "$save" ]; then
10216                         soc="obdfilter.*.sync_on_lock_cancel"
10217                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10218                 fi
10219
10220                 if [ "$save" != "never" ]; then
10221                         local hosts=$(comma_list $(osts_nodes))
10222
10223                         do_nodes $hosts $LCTL set_param $soc=never
10224                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10225                 fi
10226         fi
10227
10228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10229         sync; sleep 1; sync
10230         local before=$(date +%s)
10231         cancel_lru_locks osc
10232         local after=$(date +%s)
10233         local diff=$((after - before))
10234         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10235
10236         rm -f $DIR/$tfile
10237 }
10238 run_test 80 "Page eviction is equally fast at high offsets too"
10239
10240 test_81a() { # LU-456
10241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10242         remote_ost_nodsh && skip "remote OST with nodsh"
10243
10244         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10245         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10246         do_facet ost1 lctl set_param fail_loc=0x80000228
10247
10248         # write should trigger a retry and success
10249         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10250         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10251         RC=$?
10252         if [ $RC -ne 0 ] ; then
10253                 error "write should success, but failed for $RC"
10254         fi
10255 }
10256 run_test 81a "OST should retry write when get -ENOSPC ==============="
10257
10258 test_81b() { # LU-456
10259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10260         remote_ost_nodsh && skip "remote OST with nodsh"
10261
10262         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10263         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10264         do_facet ost1 lctl set_param fail_loc=0x228
10265
10266         # write should retry several times and return -ENOSPC finally
10267         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10268         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10269         RC=$?
10270         ENOSPC=28
10271         if [ $RC -ne $ENOSPC ] ; then
10272                 error "dd should fail for -ENOSPC, but succeed."
10273         fi
10274 }
10275 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10276
10277 test_99() {
10278         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10279
10280         test_mkdir $DIR/$tdir.cvsroot
10281         chown $RUNAS_ID $DIR/$tdir.cvsroot
10282
10283         cd $TMP
10284         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10285
10286         cd /etc/init.d
10287         # some versions of cvs import exit(1) when asked to import links or
10288         # files they can't read.  ignore those files.
10289         local toignore=$(find . -type l -printf '-I %f\n' -o \
10290                          ! -perm /4 -printf '-I %f\n')
10291         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10292                 $tdir.reposname vtag rtag
10293
10294         cd $DIR
10295         test_mkdir $DIR/$tdir.reposname
10296         chown $RUNAS_ID $DIR/$tdir.reposname
10297         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10298
10299         cd $DIR/$tdir.reposname
10300         $RUNAS touch foo99
10301         $RUNAS cvs add -m 'addmsg' foo99
10302         $RUNAS cvs update
10303         $RUNAS cvs commit -m 'nomsg' foo99
10304         rm -fr $DIR/$tdir.cvsroot
10305 }
10306 run_test 99 "cvs strange file/directory operations"
10307
10308 test_100() {
10309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10310         [[ "$NETTYPE" =~ tcp ]] ||
10311                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10312         remote_ost_nodsh && skip "remote OST with nodsh"
10313         remote_mds_nodsh && skip "remote MDS with nodsh"
10314         remote_servers ||
10315                 skip "useless for local single node setup"
10316
10317         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10318                 [ "$PROT" != "tcp" ] && continue
10319                 RPORT=$(echo $REMOTE | cut -d: -f2)
10320                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10321
10322                 rc=0
10323                 LPORT=`echo $LOCAL | cut -d: -f2`
10324                 if [ $LPORT -ge 1024 ]; then
10325                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10326                         netstat -tna
10327                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10328                 fi
10329         done
10330         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10331 }
10332 run_test 100 "check local port using privileged port ==========="
10333
10334 function get_named_value()
10335 {
10336     local tag=$1
10337
10338     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10339 }
10340
10341 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10342                    awk '/^max_cached_mb/ { print $2 }')
10343
10344 cleanup_101a() {
10345         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10346         trap 0
10347 }
10348
10349 test_101a() {
10350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10351
10352         local s
10353         local discard
10354         local nreads=10000
10355         local cache_limit=32
10356
10357         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10358         trap cleanup_101a EXIT
10359         $LCTL set_param -n llite.*.read_ahead_stats=0
10360         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10361
10362         #
10363         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10364         #
10365         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10366         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10367
10368         discard=0
10369         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10370                    get_named_value 'read.but.discarded'); do
10371                         discard=$(($discard + $s))
10372         done
10373         cleanup_101a
10374
10375         $LCTL get_param osc.*-osc*.rpc_stats
10376         $LCTL get_param llite.*.read_ahead_stats
10377
10378         # Discard is generally zero, but sometimes a few random reads line up
10379         # and trigger larger readahead, which is wasted & leads to discards.
10380         if [[ $(($discard)) -gt $nreads ]]; then
10381                 error "too many ($discard) discarded pages"
10382         fi
10383         rm -f $DIR/$tfile || true
10384 }
10385 run_test 101a "check read-ahead for random reads"
10386
10387 setup_test101bc() {
10388         test_mkdir $DIR/$tdir
10389         local ssize=$1
10390         local FILE_LENGTH=$2
10391         STRIPE_OFFSET=0
10392
10393         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10394
10395         local list=$(comma_list $(osts_nodes))
10396         set_osd_param $list '' read_cache_enable 0
10397         set_osd_param $list '' writethrough_cache_enable 0
10398
10399         trap cleanup_test101bc EXIT
10400         # prepare the read-ahead file
10401         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10402
10403         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10404                                 count=$FILE_SIZE_MB 2> /dev/null
10405
10406 }
10407
10408 cleanup_test101bc() {
10409         trap 0
10410         rm -rf $DIR/$tdir
10411         rm -f $DIR/$tfile
10412
10413         local list=$(comma_list $(osts_nodes))
10414         set_osd_param $list '' read_cache_enable 1
10415         set_osd_param $list '' writethrough_cache_enable 1
10416 }
10417
10418 calc_total() {
10419         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10420 }
10421
10422 ra_check_101() {
10423         local read_size=$1
10424         local stripe_size=$2
10425         local stride_length=$((stripe_size / read_size))
10426         local stride_width=$((stride_length * OSTCOUNT))
10427         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10428                                 (stride_width - stride_length) ))
10429         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10430                   get_named_value 'read.but.discarded' | calc_total)
10431
10432         if [[ $discard -gt $discard_limit ]]; then
10433                 $LCTL get_param llite.*.read_ahead_stats
10434                 error "($discard) discarded pages with size (${read_size})"
10435         else
10436                 echo "Read-ahead success for size ${read_size}"
10437         fi
10438 }
10439
10440 test_101b() {
10441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10442         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10443
10444         local STRIPE_SIZE=1048576
10445         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10446
10447         if [ $SLOW == "yes" ]; then
10448                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10449         else
10450                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10451         fi
10452
10453         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10454
10455         # prepare the read-ahead file
10456         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10457         cancel_lru_locks osc
10458         for BIDX in 2 4 8 16 32 64 128 256
10459         do
10460                 local BSIZE=$((BIDX*4096))
10461                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10462                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10463                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10464                 $LCTL set_param -n llite.*.read_ahead_stats=0
10465                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10466                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10467                 cancel_lru_locks osc
10468                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10469         done
10470         cleanup_test101bc
10471         true
10472 }
10473 run_test 101b "check stride-io mode read-ahead ================="
10474
10475 test_101c() {
10476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10477
10478         local STRIPE_SIZE=1048576
10479         local FILE_LENGTH=$((STRIPE_SIZE*100))
10480         local nreads=10000
10481         local rsize=65536
10482         local osc_rpc_stats
10483
10484         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10485
10486         cancel_lru_locks osc
10487         $LCTL set_param osc.*.rpc_stats=0
10488         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10489         $LCTL get_param osc.*.rpc_stats
10490         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10491                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10492                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10493                 local size
10494
10495                 if [ $lines -le 20 ]; then
10496                         echo "continue debug"
10497                         continue
10498                 fi
10499                 for size in 1 2 4 8; do
10500                         local rpc=$(echo "$stats" |
10501                                     awk '($1 == "'$size':") {print $2; exit; }')
10502                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10503                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10504                 done
10505                 echo "$osc_rpc_stats check passed!"
10506         done
10507         cleanup_test101bc
10508         true
10509 }
10510 run_test 101c "check stripe_size aligned read-ahead"
10511
10512 test_101d() {
10513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10514
10515         local file=$DIR/$tfile
10516         local sz_MB=${FILESIZE_101d:-80}
10517         local ra_MB=${READAHEAD_MB:-40}
10518
10519         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10520         [ $free_MB -lt $sz_MB ] &&
10521                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10522
10523         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10524         $LFS setstripe -c -1 $file || error "setstripe failed"
10525
10526         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10527         echo Cancel LRU locks on lustre client to flush the client cache
10528         cancel_lru_locks osc
10529
10530         echo Disable read-ahead
10531         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10532         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10533         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10534         $LCTL get_param -n llite.*.max_read_ahead_mb
10535
10536         echo "Reading the test file $file with read-ahead disabled"
10537         local sz_KB=$((sz_MB * 1024 / 4))
10538         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10539         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10540         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10541                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10542
10543         echo "Cancel LRU locks on lustre client to flush the client cache"
10544         cancel_lru_locks osc
10545         echo Enable read-ahead with ${ra_MB}MB
10546         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10547
10548         echo "Reading the test file $file with read-ahead enabled"
10549         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10550                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10551
10552         echo "read-ahead disabled time read $raOFF"
10553         echo "read-ahead enabled time read $raON"
10554
10555         rm -f $file
10556         wait_delete_completed
10557
10558         # use awk for this check instead of bash because it handles decimals
10559         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10560                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10561 }
10562 run_test 101d "file read with and without read-ahead enabled"
10563
10564 test_101e() {
10565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10566
10567         local file=$DIR/$tfile
10568         local size_KB=500  #KB
10569         local count=100
10570         local bsize=1024
10571
10572         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10573         local need_KB=$((count * size_KB))
10574         [[ $free_KB -le $need_KB ]] &&
10575                 skip_env "Need free space $need_KB, have $free_KB"
10576
10577         echo "Creating $count ${size_KB}K test files"
10578         for ((i = 0; i < $count; i++)); do
10579                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10580         done
10581
10582         echo "Cancel LRU locks on lustre client to flush the client cache"
10583         cancel_lru_locks $OSC
10584
10585         echo "Reset readahead stats"
10586         $LCTL set_param -n llite.*.read_ahead_stats=0
10587
10588         for ((i = 0; i < $count; i++)); do
10589                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10590         done
10591
10592         $LCTL get_param llite.*.max_cached_mb
10593         $LCTL get_param llite.*.read_ahead_stats
10594         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10595                      get_named_value 'misses' | calc_total)
10596
10597         for ((i = 0; i < $count; i++)); do
10598                 rm -rf $file.$i 2>/dev/null
10599         done
10600
10601         #10000 means 20% reads are missing in readahead
10602         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10603 }
10604 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10605
10606 test_101f() {
10607         which iozone || skip_env "no iozone installed"
10608
10609         local old_debug=$($LCTL get_param debug)
10610         old_debug=${old_debug#*=}
10611         $LCTL set_param debug="reada mmap"
10612
10613         # create a test file
10614         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10615
10616         echo Cancel LRU locks on lustre client to flush the client cache
10617         cancel_lru_locks osc
10618
10619         echo Reset readahead stats
10620         $LCTL set_param -n llite.*.read_ahead_stats=0
10621
10622         echo mmap read the file with small block size
10623         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10624                 > /dev/null 2>&1
10625
10626         echo checking missing pages
10627         $LCTL get_param llite.*.read_ahead_stats
10628         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10629                         get_named_value 'misses' | calc_total)
10630
10631         $LCTL set_param debug="$old_debug"
10632         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10633         rm -f $DIR/$tfile
10634 }
10635 run_test 101f "check mmap read performance"
10636
10637 test_101g_brw_size_test() {
10638         local mb=$1
10639         local pages=$((mb * 1048576 / PAGE_SIZE))
10640         local file=$DIR/$tfile
10641
10642         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10643                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10644         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10645                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10646                         return 2
10647         done
10648
10649         stack_trap "rm -f $file" EXIT
10650         $LCTL set_param -n osc.*.rpc_stats=0
10651
10652         # 10 RPCs should be enough for the test
10653         local count=10
10654         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10655                 { error "dd write ${mb} MB blocks failed"; return 3; }
10656         cancel_lru_locks osc
10657         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10658                 { error "dd write ${mb} MB blocks failed"; return 4; }
10659
10660         # calculate number of full-sized read and write RPCs
10661         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10662                 sed -n '/pages per rpc/,/^$/p' |
10663                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10664                 END { print reads,writes }'))
10665         # allow one extra full-sized read RPC for async readahead
10666         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10667                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10668         [[ ${rpcs[1]} == $count ]] ||
10669                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10670 }
10671
10672 test_101g() {
10673         remote_ost_nodsh && skip "remote OST with nodsh"
10674
10675         local rpcs
10676         local osts=$(get_facets OST)
10677         local list=$(comma_list $(osts_nodes))
10678         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10679         local brw_size="obdfilter.*.brw_size"
10680
10681         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10682
10683         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10684
10685         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10686                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10687                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10688            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10689                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10690                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10691
10692                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10693                         suffix="M"
10694
10695                 if [[ $orig_mb -lt 16 ]]; then
10696                         save_lustre_params $osts "$brw_size" > $p
10697                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10698                                 error "set 16MB RPC size failed"
10699
10700                         echo "remount client to enable new RPC size"
10701                         remount_client $MOUNT || error "remount_client failed"
10702                 fi
10703
10704                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10705                 # should be able to set brw_size=12, but no rpc_stats for that
10706                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10707         fi
10708
10709         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10710
10711         if [[ $orig_mb -lt 16 ]]; then
10712                 restore_lustre_params < $p
10713                 remount_client $MOUNT || error "remount_client restore failed"
10714         fi
10715
10716         rm -f $p $DIR/$tfile
10717 }
10718 run_test 101g "Big bulk(4/16 MiB) readahead"
10719
10720 test_101h() {
10721         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10722
10723         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10724                 error "dd 70M file failed"
10725         echo Cancel LRU locks on lustre client to flush the client cache
10726         cancel_lru_locks osc
10727
10728         echo "Reset readahead stats"
10729         $LCTL set_param -n llite.*.read_ahead_stats 0
10730
10731         echo "Read 10M of data but cross 64M bundary"
10732         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10733         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10734                      get_named_value 'misses' | calc_total)
10735         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10736         rm -f $p $DIR/$tfile
10737 }
10738 run_test 101h "Readahead should cover current read window"
10739
10740 test_101i() {
10741         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10742                 error "dd 10M file failed"
10743
10744         local max_per_file_mb=$($LCTL get_param -n \
10745                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10746         cancel_lru_locks osc
10747         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10748         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10749                 error "set max_read_ahead_per_file_mb to 1 failed"
10750
10751         echo "Reset readahead stats"
10752         $LCTL set_param llite.*.read_ahead_stats=0
10753
10754         dd if=$DIR/$tfile of=/dev/null bs=2M
10755
10756         $LCTL get_param llite.*.read_ahead_stats
10757         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10758                      awk '/misses/ { print $2 }')
10759         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10760         rm -f $DIR/$tfile
10761 }
10762 run_test 101i "allow current readahead to exceed reservation"
10763
10764 test_101j() {
10765         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10766                 error "setstripe $DIR/$tfile failed"
10767         local file_size=$((1048576 * 16))
10768         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10769         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10770
10771         echo Disable read-ahead
10772         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10773
10774         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10775         for blk in $PAGE_SIZE 1048576 $file_size; do
10776                 cancel_lru_locks osc
10777                 echo "Reset readahead stats"
10778                 $LCTL set_param -n llite.*.read_ahead_stats=0
10779                 local count=$(($file_size / $blk))
10780                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10781                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10782                              get_named_value 'failed.to.fast.read' | calc_total)
10783                 $LCTL get_param -n llite.*.read_ahead_stats
10784                 [ $miss -eq $count ] || error "expected $count got $miss"
10785         done
10786
10787         rm -f $p $DIR/$tfile
10788 }
10789 run_test 101j "A complete read block should be submitted when no RA"
10790
10791 setup_test102() {
10792         test_mkdir $DIR/$tdir
10793         chown $RUNAS_ID $DIR/$tdir
10794         STRIPE_SIZE=65536
10795         STRIPE_OFFSET=1
10796         STRIPE_COUNT=$OSTCOUNT
10797         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10798
10799         trap cleanup_test102 EXIT
10800         cd $DIR
10801         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10802         cd $DIR/$tdir
10803         for num in 1 2 3 4; do
10804                 for count in $(seq 1 $STRIPE_COUNT); do
10805                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10806                                 local size=`expr $STRIPE_SIZE \* $num`
10807                                 local file=file"$num-$idx-$count"
10808                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10809                         done
10810                 done
10811         done
10812
10813         cd $DIR
10814         $1 tar cf $TMP/f102.tar $tdir --xattrs
10815 }
10816
10817 cleanup_test102() {
10818         trap 0
10819         rm -f $TMP/f102.tar
10820         rm -rf $DIR/d0.sanity/d102
10821 }
10822
10823 test_102a() {
10824         [ "$UID" != 0 ] && skip "must run as root"
10825         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10826                 skip_env "must have user_xattr"
10827
10828         [ -z "$(which setfattr 2>/dev/null)" ] &&
10829                 skip_env "could not find setfattr"
10830
10831         local testfile=$DIR/$tfile
10832
10833         touch $testfile
10834         echo "set/get xattr..."
10835         setfattr -n trusted.name1 -v value1 $testfile ||
10836                 error "setfattr -n trusted.name1=value1 $testfile failed"
10837         getfattr -n trusted.name1 $testfile 2> /dev/null |
10838           grep "trusted.name1=.value1" ||
10839                 error "$testfile missing trusted.name1=value1"
10840
10841         setfattr -n user.author1 -v author1 $testfile ||
10842                 error "setfattr -n user.author1=author1 $testfile failed"
10843         getfattr -n user.author1 $testfile 2> /dev/null |
10844           grep "user.author1=.author1" ||
10845                 error "$testfile missing trusted.author1=author1"
10846
10847         echo "listxattr..."
10848         setfattr -n trusted.name2 -v value2 $testfile ||
10849                 error "$testfile unable to set trusted.name2"
10850         setfattr -n trusted.name3 -v value3 $testfile ||
10851                 error "$testfile unable to set trusted.name3"
10852         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10853             grep "trusted.name" | wc -l) -eq 3 ] ||
10854                 error "$testfile missing 3 trusted.name xattrs"
10855
10856         setfattr -n user.author2 -v author2 $testfile ||
10857                 error "$testfile unable to set user.author2"
10858         setfattr -n user.author3 -v author3 $testfile ||
10859                 error "$testfile unable to set user.author3"
10860         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10861             grep "user.author" | wc -l) -eq 3 ] ||
10862                 error "$testfile missing 3 user.author xattrs"
10863
10864         echo "remove xattr..."
10865         setfattr -x trusted.name1 $testfile ||
10866                 error "$testfile error deleting trusted.name1"
10867         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10868                 error "$testfile did not delete trusted.name1 xattr"
10869
10870         setfattr -x user.author1 $testfile ||
10871                 error "$testfile error deleting user.author1"
10872         echo "set lustre special xattr ..."
10873         $LFS setstripe -c1 $testfile
10874         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10875                 awk -F "=" '/trusted.lov/ { print $2 }' )
10876         setfattr -n "trusted.lov" -v $lovea $testfile ||
10877                 error "$testfile doesn't ignore setting trusted.lov again"
10878         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10879                 error "$testfile allow setting invalid trusted.lov"
10880         rm -f $testfile
10881 }
10882 run_test 102a "user xattr test =================================="
10883
10884 check_102b_layout() {
10885         local layout="$*"
10886         local testfile=$DIR/$tfile
10887
10888         echo "test layout '$layout'"
10889         $LFS setstripe $layout $testfile || error "setstripe failed"
10890         $LFS getstripe -y $testfile
10891
10892         echo "get/set/list trusted.lov xattr ..." # b=10930
10893         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10894         [[ "$value" =~ "trusted.lov" ]] ||
10895                 error "can't get trusted.lov from $testfile"
10896         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10897                 error "getstripe failed"
10898
10899         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10900
10901         value=$(cut -d= -f2 <<<$value)
10902         # LU-13168: truncated xattr should fail if short lov_user_md header
10903         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10904                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10905         for len in $lens; do
10906                 echo "setfattr $len $testfile.2"
10907                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10908                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10909         done
10910         local stripe_size=$($LFS getstripe -S $testfile.2)
10911         local stripe_count=$($LFS getstripe -c $testfile.2)
10912         [[ $stripe_size -eq 65536 ]] ||
10913                 error "stripe size $stripe_size != 65536"
10914         [[ $stripe_count -eq $stripe_count_orig ]] ||
10915                 error "stripe count $stripe_count != $stripe_count_orig"
10916         rm $testfile $testfile.2
10917 }
10918
10919 test_102b() {
10920         [ -z "$(which setfattr 2>/dev/null)" ] &&
10921                 skip_env "could not find setfattr"
10922         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10923
10924         # check plain layout
10925         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10926
10927         # and also check composite layout
10928         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10929
10930 }
10931 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10932
10933 test_102c() {
10934         [ -z "$(which setfattr 2>/dev/null)" ] &&
10935                 skip_env "could not find setfattr"
10936         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10937
10938         # b10930: get/set/list lustre.lov xattr
10939         echo "get/set/list lustre.lov xattr ..."
10940         test_mkdir $DIR/$tdir
10941         chown $RUNAS_ID $DIR/$tdir
10942         local testfile=$DIR/$tdir/$tfile
10943         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10944                 error "setstripe failed"
10945         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10946                 error "getstripe failed"
10947         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10948         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10949
10950         local testfile2=${testfile}2
10951         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10952                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10953
10954         $RUNAS $MCREATE $testfile2
10955         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10956         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10957         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10958         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10959         [ $stripe_count -eq $STRIPECOUNT ] ||
10960                 error "stripe count $stripe_count != $STRIPECOUNT"
10961 }
10962 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10963
10964 compare_stripe_info1() {
10965         local stripe_index_all_zero=true
10966
10967         for num in 1 2 3 4; do
10968                 for count in $(seq 1 $STRIPE_COUNT); do
10969                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10970                                 local size=$((STRIPE_SIZE * num))
10971                                 local file=file"$num-$offset-$count"
10972                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10973                                 [[ $stripe_size -ne $size ]] &&
10974                                     error "$file: size $stripe_size != $size"
10975                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10976                                 # allow fewer stripes to be created, ORI-601
10977                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10978                                     error "$file: count $stripe_count != $count"
10979                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10980                                 [[ $stripe_index -ne 0 ]] &&
10981                                         stripe_index_all_zero=false
10982                         done
10983                 done
10984         done
10985         $stripe_index_all_zero &&
10986                 error "all files are being extracted starting from OST index 0"
10987         return 0
10988 }
10989
10990 have_xattrs_include() {
10991         tar --help | grep -q xattrs-include &&
10992                 echo --xattrs-include="lustre.*"
10993 }
10994
10995 test_102d() {
10996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10997         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10998
10999         XINC=$(have_xattrs_include)
11000         setup_test102
11001         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11002         cd $DIR/$tdir/$tdir
11003         compare_stripe_info1
11004 }
11005 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11006
11007 test_102f() {
11008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11009         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11010
11011         XINC=$(have_xattrs_include)
11012         setup_test102
11013         test_mkdir $DIR/$tdir.restore
11014         cd $DIR
11015         tar cf - --xattrs $tdir | tar xf - \
11016                 -C $DIR/$tdir.restore --xattrs $XINC
11017         cd $DIR/$tdir.restore/$tdir
11018         compare_stripe_info1
11019 }
11020 run_test 102f "tar copy files, not keep osts"
11021
11022 grow_xattr() {
11023         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11024                 skip "must have user_xattr"
11025         [ -z "$(which setfattr 2>/dev/null)" ] &&
11026                 skip_env "could not find setfattr"
11027         [ -z "$(which getfattr 2>/dev/null)" ] &&
11028                 skip_env "could not find getfattr"
11029
11030         local xsize=${1:-1024}  # in bytes
11031         local file=$DIR/$tfile
11032         local value="$(generate_string $xsize)"
11033         local xbig=trusted.big
11034         local toobig=$2
11035
11036         touch $file
11037         log "save $xbig on $file"
11038         if [ -z "$toobig" ]
11039         then
11040                 setfattr -n $xbig -v $value $file ||
11041                         error "saving $xbig on $file failed"
11042         else
11043                 setfattr -n $xbig -v $value $file &&
11044                         error "saving $xbig on $file succeeded"
11045                 return 0
11046         fi
11047
11048         local orig=$(get_xattr_value $xbig $file)
11049         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11050
11051         local xsml=trusted.sml
11052         log "save $xsml on $file"
11053         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11054
11055         local new=$(get_xattr_value $xbig $file)
11056         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11057
11058         log "grow $xsml on $file"
11059         setfattr -n $xsml -v "$value" $file ||
11060                 error "growing $xsml on $file failed"
11061
11062         new=$(get_xattr_value $xbig $file)
11063         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11064         log "$xbig still valid after growing $xsml"
11065
11066         rm -f $file
11067 }
11068
11069 test_102h() { # bug 15777
11070         grow_xattr 1024
11071 }
11072 run_test 102h "grow xattr from inside inode to external block"
11073
11074 test_102ha() {
11075         large_xattr_enabled || skip_env "ea_inode feature disabled"
11076
11077         echo "setting xattr of max xattr size: $(max_xattr_size)"
11078         grow_xattr $(max_xattr_size)
11079
11080         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11081         echo "This should fail:"
11082         grow_xattr $(($(max_xattr_size) + 10)) 1
11083 }
11084 run_test 102ha "grow xattr from inside inode to external inode"
11085
11086 test_102i() { # bug 17038
11087         [ -z "$(which getfattr 2>/dev/null)" ] &&
11088                 skip "could not find getfattr"
11089
11090         touch $DIR/$tfile
11091         ln -s $DIR/$tfile $DIR/${tfile}link
11092         getfattr -n trusted.lov $DIR/$tfile ||
11093                 error "lgetxattr on $DIR/$tfile failed"
11094         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11095                 grep -i "no such attr" ||
11096                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11097         rm -f $DIR/$tfile $DIR/${tfile}link
11098 }
11099 run_test 102i "lgetxattr test on symbolic link ============"
11100
11101 test_102j() {
11102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11104
11105         XINC=$(have_xattrs_include)
11106         setup_test102 "$RUNAS"
11107         chown $RUNAS_ID $DIR/$tdir
11108         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11109         cd $DIR/$tdir/$tdir
11110         compare_stripe_info1 "$RUNAS"
11111 }
11112 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11113
11114 test_102k() {
11115         [ -z "$(which setfattr 2>/dev/null)" ] &&
11116                 skip "could not find setfattr"
11117
11118         touch $DIR/$tfile
11119         # b22187 just check that does not crash for regular file.
11120         setfattr -n trusted.lov $DIR/$tfile
11121         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11122         local test_kdir=$DIR/$tdir
11123         test_mkdir $test_kdir
11124         local default_size=$($LFS getstripe -S $test_kdir)
11125         local default_count=$($LFS getstripe -c $test_kdir)
11126         local default_offset=$($LFS getstripe -i $test_kdir)
11127         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11128                 error 'dir setstripe failed'
11129         setfattr -n trusted.lov $test_kdir
11130         local stripe_size=$($LFS getstripe -S $test_kdir)
11131         local stripe_count=$($LFS getstripe -c $test_kdir)
11132         local stripe_offset=$($LFS getstripe -i $test_kdir)
11133         [ $stripe_size -eq $default_size ] ||
11134                 error "stripe size $stripe_size != $default_size"
11135         [ $stripe_count -eq $default_count ] ||
11136                 error "stripe count $stripe_count != $default_count"
11137         [ $stripe_offset -eq $default_offset ] ||
11138                 error "stripe offset $stripe_offset != $default_offset"
11139         rm -rf $DIR/$tfile $test_kdir
11140 }
11141 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11142
11143 test_102l() {
11144         [ -z "$(which getfattr 2>/dev/null)" ] &&
11145                 skip "could not find getfattr"
11146
11147         # LU-532 trusted. xattr is invisible to non-root
11148         local testfile=$DIR/$tfile
11149
11150         touch $testfile
11151
11152         echo "listxattr as user..."
11153         chown $RUNAS_ID $testfile
11154         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11155             grep -q "trusted" &&
11156                 error "$testfile trusted xattrs are user visible"
11157
11158         return 0;
11159 }
11160 run_test 102l "listxattr size test =================================="
11161
11162 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11163         local path=$DIR/$tfile
11164         touch $path
11165
11166         listxattr_size_check $path || error "listattr_size_check $path failed"
11167 }
11168 run_test 102m "Ensure listxattr fails on small bufffer ========"
11169
11170 cleanup_test102
11171
11172 getxattr() { # getxattr path name
11173         # Return the base64 encoding of the value of xattr name on path.
11174         local path=$1
11175         local name=$2
11176
11177         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11178         # file: $path
11179         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11180         #
11181         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11182
11183         getfattr --absolute-names --encoding=base64 --name=$name $path |
11184                 awk -F= -v name=$name '$1 == name {
11185                         print substr($0, index($0, "=") + 1);
11186         }'
11187 }
11188
11189 test_102n() { # LU-4101 mdt: protect internal xattrs
11190         [ -z "$(which setfattr 2>/dev/null)" ] &&
11191                 skip "could not find setfattr"
11192         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11193         then
11194                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11195         fi
11196
11197         local file0=$DIR/$tfile.0
11198         local file1=$DIR/$tfile.1
11199         local xattr0=$TMP/$tfile.0
11200         local xattr1=$TMP/$tfile.1
11201         local namelist="lov lma lmv link fid version som hsm"
11202         local name
11203         local value
11204
11205         rm -rf $file0 $file1 $xattr0 $xattr1
11206         touch $file0 $file1
11207
11208         # Get 'before' xattrs of $file1.
11209         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11210
11211         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11212                 namelist+=" lfsck_namespace"
11213         for name in $namelist; do
11214                 # Try to copy xattr from $file0 to $file1.
11215                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11216
11217                 setfattr --name=trusted.$name --value="$value" $file1 ||
11218                         error "setxattr 'trusted.$name' failed"
11219
11220                 # Try to set a garbage xattr.
11221                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11222
11223                 if [[ x$name == "xlov" ]]; then
11224                         setfattr --name=trusted.lov --value="$value" $file1 &&
11225                         error "setxattr invalid 'trusted.lov' success"
11226                 else
11227                         setfattr --name=trusted.$name --value="$value" $file1 ||
11228                                 error "setxattr invalid 'trusted.$name' failed"
11229                 fi
11230
11231                 # Try to remove the xattr from $file1. We don't care if this
11232                 # appears to succeed or fail, we just don't want there to be
11233                 # any changes or crashes.
11234                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11235         done
11236
11237         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11238         then
11239                 name="lfsck_ns"
11240                 # Try to copy xattr from $file0 to $file1.
11241                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11242
11243                 setfattr --name=trusted.$name --value="$value" $file1 ||
11244                         error "setxattr 'trusted.$name' failed"
11245
11246                 # Try to set a garbage xattr.
11247                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11248
11249                 setfattr --name=trusted.$name --value="$value" $file1 ||
11250                         error "setxattr 'trusted.$name' failed"
11251
11252                 # Try to remove the xattr from $file1. We don't care if this
11253                 # appears to succeed or fail, we just don't want there to be
11254                 # any changes or crashes.
11255                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11256         fi
11257
11258         # Get 'after' xattrs of file1.
11259         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11260
11261         if ! diff $xattr0 $xattr1; then
11262                 error "before and after xattrs of '$file1' differ"
11263         fi
11264
11265         rm -rf $file0 $file1 $xattr0 $xattr1
11266
11267         return 0
11268 }
11269 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11270
11271 test_102p() { # LU-4703 setxattr did not check ownership
11272         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11273                 skip "MDS needs to be at least 2.5.56"
11274
11275         local testfile=$DIR/$tfile
11276
11277         touch $testfile
11278
11279         echo "setfacl as user..."
11280         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11281         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11282
11283         echo "setfattr as user..."
11284         setfacl -m "u:$RUNAS_ID:---" $testfile
11285         $RUNAS setfattr -x system.posix_acl_access $testfile
11286         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11287 }
11288 run_test 102p "check setxattr(2) correctly fails without permission"
11289
11290 test_102q() {
11291         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11292                 skip "MDS needs to be at least 2.6.92"
11293
11294         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11295 }
11296 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11297
11298 test_102r() {
11299         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11300                 skip "MDS needs to be at least 2.6.93"
11301
11302         touch $DIR/$tfile || error "touch"
11303         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11304         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11305         rm $DIR/$tfile || error "rm"
11306
11307         #normal directory
11308         mkdir -p $DIR/$tdir || error "mkdir"
11309         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11310         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11311         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11312                 error "$testfile error deleting user.author1"
11313         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11314                 grep "user.$(basename $tdir)" &&
11315                 error "$tdir did not delete user.$(basename $tdir)"
11316         rmdir $DIR/$tdir || error "rmdir"
11317
11318         #striped directory
11319         test_mkdir $DIR/$tdir
11320         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11321         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11322         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11323                 error "$testfile error deleting user.author1"
11324         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11325                 grep "user.$(basename $tdir)" &&
11326                 error "$tdir did not delete user.$(basename $tdir)"
11327         rmdir $DIR/$tdir || error "rm striped dir"
11328 }
11329 run_test 102r "set EAs with empty values"
11330
11331 test_102s() {
11332         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11333                 skip "MDS needs to be at least 2.11.52"
11334
11335         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11336
11337         save_lustre_params client "llite.*.xattr_cache" > $save
11338
11339         for cache in 0 1; do
11340                 lctl set_param llite.*.xattr_cache=$cache
11341
11342                 rm -f $DIR/$tfile
11343                 touch $DIR/$tfile || error "touch"
11344                 for prefix in lustre security system trusted user; do
11345                         # Note getxattr() may fail with 'Operation not
11346                         # supported' or 'No such attribute' depending
11347                         # on prefix and cache.
11348                         getfattr -n $prefix.n102s $DIR/$tfile &&
11349                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11350                 done
11351         done
11352
11353         restore_lustre_params < $save
11354 }
11355 run_test 102s "getting nonexistent xattrs should fail"
11356
11357 test_102t() {
11358         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11359                 skip "MDS needs to be at least 2.11.52"
11360
11361         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11362
11363         save_lustre_params client "llite.*.xattr_cache" > $save
11364
11365         for cache in 0 1; do
11366                 lctl set_param llite.*.xattr_cache=$cache
11367
11368                 for buf_size in 0 256; do
11369                         rm -f $DIR/$tfile
11370                         touch $DIR/$tfile || error "touch"
11371                         setfattr -n user.multiop $DIR/$tfile
11372                         $MULTIOP $DIR/$tfile oa$buf_size ||
11373                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11374                 done
11375         done
11376
11377         restore_lustre_params < $save
11378 }
11379 run_test 102t "zero length xattr values handled correctly"
11380
11381 run_acl_subtest()
11382 {
11383     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11384     return $?
11385 }
11386
11387 test_103a() {
11388         [ "$UID" != 0 ] && skip "must run as root"
11389         $GSS && skip_env "could not run under gss"
11390         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11391                 skip_env "must have acl enabled"
11392         [ -z "$(which setfacl 2>/dev/null)" ] &&
11393                 skip_env "could not find setfacl"
11394         remote_mds_nodsh && skip "remote MDS with nodsh"
11395
11396         gpasswd -a daemon bin                           # LU-5641
11397         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11398
11399         declare -a identity_old
11400
11401         for num in $(seq $MDSCOUNT); do
11402                 switch_identity $num true || identity_old[$num]=$?
11403         done
11404
11405         SAVE_UMASK=$(umask)
11406         umask 0022
11407         mkdir -p $DIR/$tdir
11408         cd $DIR/$tdir
11409
11410         echo "performing cp ..."
11411         run_acl_subtest cp || error "run_acl_subtest cp failed"
11412         echo "performing getfacl-noacl..."
11413         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11414         echo "performing misc..."
11415         run_acl_subtest misc || error  "misc test failed"
11416         echo "performing permissions..."
11417         run_acl_subtest permissions || error "permissions failed"
11418         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11419         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11420                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11421                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11422         then
11423                 echo "performing permissions xattr..."
11424                 run_acl_subtest permissions_xattr ||
11425                         error "permissions_xattr failed"
11426         fi
11427         echo "performing setfacl..."
11428         run_acl_subtest setfacl || error  "setfacl test failed"
11429
11430         # inheritance test got from HP
11431         echo "performing inheritance..."
11432         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11433         chmod +x make-tree || error "chmod +x failed"
11434         run_acl_subtest inheritance || error "inheritance test failed"
11435         rm -f make-tree
11436
11437         echo "LU-974 ignore umask when acl is enabled..."
11438         run_acl_subtest 974 || error "LU-974 umask test failed"
11439         if [ $MDSCOUNT -ge 2 ]; then
11440                 run_acl_subtest 974_remote ||
11441                         error "LU-974 umask test failed under remote dir"
11442         fi
11443
11444         echo "LU-2561 newly created file is same size as directory..."
11445         if [ "$mds1_FSTYPE" != "zfs" ]; then
11446                 run_acl_subtest 2561 || error "LU-2561 test failed"
11447         else
11448                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11449         fi
11450
11451         run_acl_subtest 4924 || error "LU-4924 test failed"
11452
11453         cd $SAVE_PWD
11454         umask $SAVE_UMASK
11455
11456         for num in $(seq $MDSCOUNT); do
11457                 if [ "${identity_old[$num]}" = 1 ]; then
11458                         switch_identity $num false || identity_old[$num]=$?
11459                 fi
11460         done
11461 }
11462 run_test 103a "acl test"
11463
11464 test_103b() {
11465         declare -a pids
11466         local U
11467
11468         for U in {0..511}; do
11469                 {
11470                 local O=$(printf "%04o" $U)
11471
11472                 umask $(printf "%04o" $((511 ^ $O)))
11473                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11474                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11475
11476                 (( $S == ($O & 0666) )) ||
11477                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11478
11479                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11480                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11481                 (( $S == ($O & 0666) )) ||
11482                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11483
11484                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11485                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11486                 (( $S == ($O & 0666) )) ||
11487                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11488                 rm -f $DIR/$tfile.[smp]$0
11489                 } &
11490                 local pid=$!
11491
11492                 # limit the concurrently running threads to 64. LU-11878
11493                 local idx=$((U % 64))
11494                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11495                 pids[idx]=$pid
11496         done
11497         wait
11498 }
11499 run_test 103b "umask lfs setstripe"
11500
11501 test_103c() {
11502         mkdir -p $DIR/$tdir
11503         cp -rp $DIR/$tdir $DIR/$tdir.bak
11504
11505         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11506                 error "$DIR/$tdir shouldn't contain default ACL"
11507         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11508                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11509         true
11510 }
11511 run_test 103c "'cp -rp' won't set empty acl"
11512
11513 test_103e() {
11514         local numacl
11515         local fileacl
11516         local saved_debug=$($LCTL get_param -n debug)
11517
11518         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11519                 skip "MDS needs to be at least 2.14.52"
11520
11521         large_xattr_enabled || skip_env "ea_inode feature disabled"
11522
11523         mkdir -p $DIR/$tdir
11524         # add big LOV EA to cause reply buffer overflow earlier
11525         $LFS setstripe -C 1000 $DIR/$tdir
11526         lctl set_param mdc.*-mdc*.stats=clear
11527
11528         $LCTL set_param debug=0
11529         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11530         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11531
11532         # add a large number of default ACLs (expect 8000+ for 2.13+)
11533         for U in {2..7000}; do
11534                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11535                         error "Able to add just $U default ACLs"
11536         done
11537         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11538         echo "$numacl default ACLs created"
11539
11540         stat $DIR/$tdir || error "Cannot stat directory"
11541         # check file creation
11542         touch $DIR/$tdir/$tfile ||
11543                 error "failed to create $tfile with $numacl default ACLs"
11544         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11545         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11546         echo "$fileacl ACLs were inherited"
11547         (( $fileacl == $numacl )) ||
11548                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11549         # check that new ACLs creation adds new ACLs to inherited ACLs
11550         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11551                 error "Cannot set new ACL"
11552         numacl=$((numacl + 1))
11553         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11554         (( $fileacl == $numacl )) ||
11555                 error "failed to add new ACL: $fileacl != $numacl as expected"
11556         # adds more ACLs to a file to reach their maximum at 8000+
11557         numacl=0
11558         for U in {20000..25000}; do
11559                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11560                 numacl=$((numacl + 1))
11561         done
11562         echo "Added $numacl more ACLs to the file"
11563         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11564         echo "Total $fileacl ACLs in file"
11565         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11566         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11567         rmdir $DIR/$tdir || error "Cannot remove directory"
11568 }
11569 run_test 103e "inheritance of big amount of default ACLs"
11570
11571 test_103f() {
11572         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11573                 skip "MDS needs to be at least 2.14.51"
11574
11575         large_xattr_enabled || skip_env "ea_inode feature disabled"
11576
11577         # enable changelog to consume more internal MDD buffers
11578         changelog_register
11579
11580         mkdir -p $DIR/$tdir
11581         # add big LOV EA
11582         $LFS setstripe -C 1000 $DIR/$tdir
11583         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11584         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11585         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11586         rmdir $DIR/$tdir || error "Cannot remove directory"
11587 }
11588 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11589
11590 test_104a() {
11591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11592
11593         touch $DIR/$tfile
11594         lfs df || error "lfs df failed"
11595         lfs df -ih || error "lfs df -ih failed"
11596         lfs df -h $DIR || error "lfs df -h $DIR failed"
11597         lfs df -i $DIR || error "lfs df -i $DIR failed"
11598         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11599         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11600
11601         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11602         lctl --device %$OSC deactivate
11603         lfs df || error "lfs df with deactivated OSC failed"
11604         lctl --device %$OSC activate
11605         # wait the osc back to normal
11606         wait_osc_import_ready client ost
11607
11608         lfs df || error "lfs df with reactivated OSC failed"
11609         rm -f $DIR/$tfile
11610 }
11611 run_test 104a "lfs df [-ih] [path] test ========================="
11612
11613 test_104b() {
11614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11615         [ $RUNAS_ID -eq $UID ] &&
11616                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11617
11618         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11619                         grep "Permission denied" | wc -l)))
11620         if [ $denied_cnt -ne 0 ]; then
11621                 error "lfs check servers test failed"
11622         fi
11623 }
11624 run_test 104b "$RUNAS lfs check servers test ===================="
11625
11626 #
11627 # Verify $1 is within range of $2.
11628 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11629 # $1 is <= 2% of $2. Else Fail.
11630 #
11631 value_in_range() {
11632         # Strip all units (M, G, T)
11633         actual=$(echo $1 | tr -d A-Z)
11634         expect=$(echo $2 | tr -d A-Z)
11635
11636         expect_lo=$(($expect * 98 / 100)) # 2% below
11637         expect_hi=$(($expect * 102 / 100)) # 2% above
11638
11639         # permit 2% drift above and below
11640         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11641 }
11642
11643 test_104c() {
11644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11645         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11646
11647         local ost_param="osd-zfs.$FSNAME-OST0000."
11648         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11649         local ofacets=$(get_facets OST)
11650         local mfacets=$(get_facets MDS)
11651         local saved_ost_blocks=
11652         local saved_mdt_blocks=
11653
11654         echo "Before recordsize change"
11655         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11656         df=($(df -h | grep "/mnt/lustre"$))
11657
11658         # For checking.
11659         echo "lfs output : ${lfs_df[*]}"
11660         echo "df  output : ${df[*]}"
11661
11662         for facet in ${ofacets//,/ }; do
11663                 if [ -z $saved_ost_blocks ]; then
11664                         saved_ost_blocks=$(do_facet $facet \
11665                                 lctl get_param -n $ost_param.blocksize)
11666                         echo "OST Blocksize: $saved_ost_blocks"
11667                 fi
11668                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11669                 do_facet $facet zfs set recordsize=32768 $ost
11670         done
11671
11672         # BS too small. Sufficient for functional testing.
11673         for facet in ${mfacets//,/ }; do
11674                 if [ -z $saved_mdt_blocks ]; then
11675                         saved_mdt_blocks=$(do_facet $facet \
11676                                 lctl get_param -n $mdt_param.blocksize)
11677                         echo "MDT Blocksize: $saved_mdt_blocks"
11678                 fi
11679                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11680                 do_facet $facet zfs set recordsize=32768 $mdt
11681         done
11682
11683         # Give new values chance to reflect change
11684         sleep 2
11685
11686         echo "After recordsize change"
11687         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11688         df_after=($(df -h | grep "/mnt/lustre"$))
11689
11690         # For checking.
11691         echo "lfs output : ${lfs_df_after[*]}"
11692         echo "df  output : ${df_after[*]}"
11693
11694         # Verify lfs df
11695         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11696                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11697         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11698                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11699         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11700                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11701
11702         # Verify df
11703         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11704                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11705         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11706                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11707         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11708                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11709
11710         # Restore MDT recordize back to original
11711         for facet in ${mfacets//,/ }; do
11712                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11713                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11714         done
11715
11716         # Restore OST recordize back to original
11717         for facet in ${ofacets//,/ }; do
11718                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11719                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11720         done
11721
11722         return 0
11723 }
11724 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11725
11726 test_105a() {
11727         # doesn't work on 2.4 kernels
11728         touch $DIR/$tfile
11729         if $(flock_is_enabled); then
11730                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11731         else
11732                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11733         fi
11734         rm -f $DIR/$tfile
11735 }
11736 run_test 105a "flock when mounted without -o flock test ========"
11737
11738 test_105b() {
11739         touch $DIR/$tfile
11740         if $(flock_is_enabled); then
11741                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11742         else
11743                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11744         fi
11745         rm -f $DIR/$tfile
11746 }
11747 run_test 105b "fcntl when mounted without -o flock test ========"
11748
11749 test_105c() {
11750         touch $DIR/$tfile
11751         if $(flock_is_enabled); then
11752                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11753         else
11754                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11755         fi
11756         rm -f $DIR/$tfile
11757 }
11758 run_test 105c "lockf when mounted without -o flock test"
11759
11760 test_105d() { # bug 15924
11761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11762
11763         test_mkdir $DIR/$tdir
11764         flock_is_enabled || skip_env "mount w/o flock enabled"
11765         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11766         $LCTL set_param fail_loc=0x80000315
11767         flocks_test 2 $DIR/$tdir
11768 }
11769 run_test 105d "flock race (should not freeze) ========"
11770
11771 test_105e() { # bug 22660 && 22040
11772         flock_is_enabled || skip_env "mount w/o flock enabled"
11773
11774         touch $DIR/$tfile
11775         flocks_test 3 $DIR/$tfile
11776 }
11777 run_test 105e "Two conflicting flocks from same process"
11778
11779 test_106() { #bug 10921
11780         test_mkdir $DIR/$tdir
11781         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11782         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11783 }
11784 run_test 106 "attempt exec of dir followed by chown of that dir"
11785
11786 test_107() {
11787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11788
11789         CDIR=`pwd`
11790         local file=core
11791
11792         cd $DIR
11793         rm -f $file
11794
11795         local save_pattern=$(sysctl -n kernel.core_pattern)
11796         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11797         sysctl -w kernel.core_pattern=$file
11798         sysctl -w kernel.core_uses_pid=0
11799
11800         ulimit -c unlimited
11801         sleep 60 &
11802         SLEEPPID=$!
11803
11804         sleep 1
11805
11806         kill -s 11 $SLEEPPID
11807         wait $SLEEPPID
11808         if [ -e $file ]; then
11809                 size=`stat -c%s $file`
11810                 [ $size -eq 0 ] && error "Fail to create core file $file"
11811         else
11812                 error "Fail to create core file $file"
11813         fi
11814         rm -f $file
11815         sysctl -w kernel.core_pattern=$save_pattern
11816         sysctl -w kernel.core_uses_pid=$save_uses_pid
11817         cd $CDIR
11818 }
11819 run_test 107 "Coredump on SIG"
11820
11821 test_110() {
11822         test_mkdir $DIR/$tdir
11823         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11824         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11825                 error "mkdir with 256 char should fail, but did not"
11826         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11827                 error "create with 255 char failed"
11828         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11829                 error "create with 256 char should fail, but did not"
11830
11831         ls -l $DIR/$tdir
11832         rm -rf $DIR/$tdir
11833 }
11834 run_test 110 "filename length checking"
11835
11836 #
11837 # Purpose: To verify dynamic thread (OSS) creation.
11838 #
11839 test_115() {
11840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11841         remote_ost_nodsh && skip "remote OST with nodsh"
11842
11843         # Lustre does not stop service threads once they are started.
11844         # Reset number of running threads to default.
11845         stopall
11846         setupall
11847
11848         local OSTIO_pre
11849         local save_params="$TMP/sanity-$TESTNAME.parameters"
11850
11851         # Get ll_ost_io count before I/O
11852         OSTIO_pre=$(do_facet ost1 \
11853                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11854         # Exit if lustre is not running (ll_ost_io not running).
11855         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11856
11857         echo "Starting with $OSTIO_pre threads"
11858         local thread_max=$((OSTIO_pre * 2))
11859         local rpc_in_flight=$((thread_max * 2))
11860         # this is limited to OSC_MAX_RIF_MAX (256)
11861         [ $rpc_in_flight -gt 256 ] && rpc_in_flight=256
11862         thread_max=$((rpc_in_flight / 2))
11863         [ $thread_max -le $OSTIO_pre ] && skip "Too many ost_io threads" &&
11864                 return
11865
11866         # Number of I/O Process proposed to be started.
11867         local nfiles
11868         local facets=$(get_facets OST)
11869
11870         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11871         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11872
11873         # Set in_flight to $rpc_in_flight
11874         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11875                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11876         nfiles=${rpc_in_flight}
11877         # Set ost thread_max to $thread_max
11878         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11879
11880         # 5 Minutes should be sufficient for max number of OSS
11881         # threads(thread_max) to be created.
11882         local timeout=300
11883
11884         # Start I/O.
11885         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11886         test_mkdir $DIR/$tdir
11887         for i in $(seq $nfiles); do
11888                 local file=$DIR/$tdir/${tfile}-$i
11889                 $LFS setstripe -c -1 -i 0 $file
11890                 ($WTL $file $timeout)&
11891         done
11892
11893         # I/O Started - Wait for thread_started to reach thread_max or report
11894         # error if thread_started is more than thread_max.
11895         echo "Waiting for thread_started to reach thread_max"
11896         local thread_started=0
11897         local end_time=$((SECONDS + timeout))
11898
11899         while [ $SECONDS -le $end_time ] ; do
11900                 echo -n "."
11901                 # Get ost i/o thread_started count.
11902                 thread_started=$(do_facet ost1 \
11903                         "$LCTL get_param \
11904                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11905                 # Break out if thread_started is equal/greater than thread_max
11906                 if [[ $thread_started -ge $thread_max ]]; then
11907                         echo ll_ost_io thread_started $thread_started, \
11908                                 equal/greater than thread_max $thread_max
11909                         break
11910                 fi
11911                 sleep 1
11912         done
11913
11914         # Cleanup - We have the numbers, Kill i/o jobs if running.
11915         jobcount=($(jobs -p))
11916         for i in $(seq 0 $((${#jobcount[@]}-1)))
11917         do
11918                 kill -9 ${jobcount[$i]}
11919                 if [ $? -ne 0 ] ; then
11920                         echo Warning: \
11921                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11922                 fi
11923         done
11924
11925         # Cleanup files left by WTL binary.
11926         for i in $(seq $nfiles); do
11927                 local file=$DIR/$tdir/${tfile}-$i
11928                 rm -rf $file
11929                 if [ $? -ne 0 ] ; then
11930                         echo "Warning: Failed to delete file $file"
11931                 fi
11932         done
11933
11934         restore_lustre_params <$save_params
11935         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11936
11937         # Error out if no new thread has started or Thread started is greater
11938         # than thread max.
11939         if [[ $thread_started -le $OSTIO_pre ||
11940                         $thread_started -gt $thread_max ]]; then
11941                 error "ll_ost_io: thread_started $thread_started" \
11942                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11943                       "No new thread started or thread started greater " \
11944                       "than thread_max."
11945         fi
11946 }
11947 run_test 115 "verify dynamic thread creation===================="
11948
11949 free_min_max () {
11950         wait_delete_completed
11951         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11952         echo "OST kbytes available: ${AVAIL[*]}"
11953         MAXV=${AVAIL[0]}
11954         MAXI=0
11955         MINV=${AVAIL[0]}
11956         MINI=0
11957         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11958                 #echo OST $i: ${AVAIL[i]}kb
11959                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11960                         MAXV=${AVAIL[i]}
11961                         MAXI=$i
11962                 fi
11963                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11964                         MINV=${AVAIL[i]}
11965                         MINI=$i
11966                 fi
11967         done
11968         echo "Min free space: OST $MINI: $MINV"
11969         echo "Max free space: OST $MAXI: $MAXV"
11970 }
11971
11972 test_116a() { # was previously test_116()
11973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11974         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11975         remote_mds_nodsh && skip "remote MDS with nodsh"
11976
11977         echo -n "Free space priority "
11978         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11979                 head -n1
11980         declare -a AVAIL
11981         free_min_max
11982
11983         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11984         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11985         stack_trap simple_cleanup_common
11986
11987         # Check if we need to generate uneven OSTs
11988         test_mkdir -p $DIR/$tdir/OST${MINI}
11989         local FILL=$((MINV / 4))
11990         local DIFF=$((MAXV - MINV))
11991         local DIFF2=$((DIFF * 100 / MINV))
11992
11993         local threshold=$(do_facet $SINGLEMDS \
11994                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11995         threshold=${threshold%%%}
11996         echo -n "Check for uneven OSTs: "
11997         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11998
11999         if [[ $DIFF2 -gt $threshold ]]; then
12000                 echo "ok"
12001                 echo "Don't need to fill OST$MINI"
12002         else
12003                 # generate uneven OSTs. Write 2% over the QOS threshold value
12004                 echo "no"
12005                 DIFF=$((threshold - DIFF2 + 2))
12006                 DIFF2=$((MINV * DIFF / 100))
12007                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12008                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12009                         error "setstripe failed"
12010                 DIFF=$((DIFF2 / 2048))
12011                 i=0
12012                 while [ $i -lt $DIFF ]; do
12013                         i=$((i + 1))
12014                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12015                                 bs=2M count=1 2>/dev/null
12016                         echo -n .
12017                 done
12018                 echo .
12019                 sync
12020                 sleep_maxage
12021                 free_min_max
12022         fi
12023
12024         DIFF=$((MAXV - MINV))
12025         DIFF2=$((DIFF * 100 / MINV))
12026         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12027         if [ $DIFF2 -gt $threshold ]; then
12028                 echo "ok"
12029         else
12030                 skip "QOS imbalance criteria not met"
12031         fi
12032
12033         MINI1=$MINI
12034         MINV1=$MINV
12035         MAXI1=$MAXI
12036         MAXV1=$MAXV
12037
12038         # now fill using QOS
12039         $LFS setstripe -c 1 $DIR/$tdir
12040         FILL=$((FILL / 200))
12041         if [ $FILL -gt 600 ]; then
12042                 FILL=600
12043         fi
12044         echo "writing $FILL files to QOS-assigned OSTs"
12045         i=0
12046         while [ $i -lt $FILL ]; do
12047                 i=$((i + 1))
12048                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12049                         count=1 2>/dev/null
12050                 echo -n .
12051         done
12052         echo "wrote $i 200k files"
12053         sync
12054         sleep_maxage
12055
12056         echo "Note: free space may not be updated, so measurements might be off"
12057         free_min_max
12058         DIFF2=$((MAXV - MINV))
12059         echo "free space delta: orig $DIFF final $DIFF2"
12060         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12061         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12062         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12063         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12064         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12065         if [[ $DIFF -gt 0 ]]; then
12066                 FILL=$((DIFF2 * 100 / DIFF - 100))
12067                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12068         fi
12069
12070         # Figure out which files were written where
12071         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12072                awk '/'$MINI1': / {print $2; exit}')
12073         echo $UUID
12074         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12075         echo "$MINC files created on smaller OST $MINI1"
12076         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12077                awk '/'$MAXI1': / {print $2; exit}')
12078         echo $UUID
12079         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12080         echo "$MAXC files created on larger OST $MAXI1"
12081         if [[ $MINC -gt 0 ]]; then
12082                 FILL=$((MAXC * 100 / MINC - 100))
12083                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12084         fi
12085         [[ $MAXC -gt $MINC ]] ||
12086                 error_ignore LU-9 "stripe QOS didn't balance free space"
12087 }
12088 run_test 116a "stripe QOS: free space balance ==================="
12089
12090 test_116b() { # LU-2093
12091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12092         remote_mds_nodsh && skip "remote MDS with nodsh"
12093
12094 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12095         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12096                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12097         [ -z "$old_rr" ] && skip "no QOS"
12098         do_facet $SINGLEMDS lctl set_param \
12099                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12100         mkdir -p $DIR/$tdir
12101         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12102         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12103         do_facet $SINGLEMDS lctl set_param fail_loc=0
12104         rm -rf $DIR/$tdir
12105         do_facet $SINGLEMDS lctl set_param \
12106                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12107 }
12108 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12109
12110 test_117() # bug 10891
12111 {
12112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12113
12114         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12115         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12116         lctl set_param fail_loc=0x21e
12117         > $DIR/$tfile || error "truncate failed"
12118         lctl set_param fail_loc=0
12119         echo "Truncate succeeded."
12120         rm -f $DIR/$tfile
12121 }
12122 run_test 117 "verify osd extend =========="
12123
12124 NO_SLOW_RESENDCOUNT=4
12125 export OLD_RESENDCOUNT=""
12126 set_resend_count () {
12127         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12128         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12129         lctl set_param -n $PROC_RESENDCOUNT $1
12130         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12131 }
12132
12133 # for reduce test_118* time (b=14842)
12134 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12135
12136 # Reset async IO behavior after error case
12137 reset_async() {
12138         FILE=$DIR/reset_async
12139
12140         # Ensure all OSCs are cleared
12141         $LFS setstripe -c -1 $FILE
12142         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12143         sync
12144         rm $FILE
12145 }
12146
12147 test_118a() #bug 11710
12148 {
12149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12150
12151         reset_async
12152
12153         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12154         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12155         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12156
12157         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12158                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12159                 return 1;
12160         fi
12161         rm -f $DIR/$tfile
12162 }
12163 run_test 118a "verify O_SYNC works =========="
12164
12165 test_118b()
12166 {
12167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12168         remote_ost_nodsh && skip "remote OST with nodsh"
12169
12170         reset_async
12171
12172         #define OBD_FAIL_SRV_ENOENT 0x217
12173         set_nodes_failloc "$(osts_nodes)" 0x217
12174         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12175         RC=$?
12176         set_nodes_failloc "$(osts_nodes)" 0
12177         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12178         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12179                     grep -c writeback)
12180
12181         if [[ $RC -eq 0 ]]; then
12182                 error "Must return error due to dropped pages, rc=$RC"
12183                 return 1;
12184         fi
12185
12186         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12187                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12188                 return 1;
12189         fi
12190
12191         echo "Dirty pages not leaked on ENOENT"
12192
12193         # Due to the above error the OSC will issue all RPCs syncronously
12194         # until a subsequent RPC completes successfully without error.
12195         $MULTIOP $DIR/$tfile Ow4096yc
12196         rm -f $DIR/$tfile
12197
12198         return 0
12199 }
12200 run_test 118b "Reclaim dirty pages on fatal error =========="
12201
12202 test_118c()
12203 {
12204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12205
12206         # for 118c, restore the original resend count, LU-1940
12207         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12208                                 set_resend_count $OLD_RESENDCOUNT
12209         remote_ost_nodsh && skip "remote OST with nodsh"
12210
12211         reset_async
12212
12213         #define OBD_FAIL_OST_EROFS               0x216
12214         set_nodes_failloc "$(osts_nodes)" 0x216
12215
12216         # multiop should block due to fsync until pages are written
12217         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12218         MULTIPID=$!
12219         sleep 1
12220
12221         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12222                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12223         fi
12224
12225         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12226                     grep -c writeback)
12227         if [[ $WRITEBACK -eq 0 ]]; then
12228                 error "No page in writeback, writeback=$WRITEBACK"
12229         fi
12230
12231         set_nodes_failloc "$(osts_nodes)" 0
12232         wait $MULTIPID
12233         RC=$?
12234         if [[ $RC -ne 0 ]]; then
12235                 error "Multiop fsync failed, rc=$RC"
12236         fi
12237
12238         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12239         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12240                     grep -c writeback)
12241         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12242                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12243         fi
12244
12245         rm -f $DIR/$tfile
12246         echo "Dirty pages flushed via fsync on EROFS"
12247         return 0
12248 }
12249 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12250
12251 # continue to use small resend count to reduce test_118* time (b=14842)
12252 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12253
12254 test_118d()
12255 {
12256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12257         remote_ost_nodsh && skip "remote OST with nodsh"
12258
12259         reset_async
12260
12261         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12262         set_nodes_failloc "$(osts_nodes)" 0x214
12263         # multiop should block due to fsync until pages are written
12264         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12265         MULTIPID=$!
12266         sleep 1
12267
12268         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12269                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12270         fi
12271
12272         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12273                     grep -c writeback)
12274         if [[ $WRITEBACK -eq 0 ]]; then
12275                 error "No page in writeback, writeback=$WRITEBACK"
12276         fi
12277
12278         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12279         set_nodes_failloc "$(osts_nodes)" 0
12280
12281         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12282         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12283                     grep -c writeback)
12284         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12285                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12286         fi
12287
12288         rm -f $DIR/$tfile
12289         echo "Dirty pages gaurenteed flushed via fsync"
12290         return 0
12291 }
12292 run_test 118d "Fsync validation inject a delay of the bulk =========="
12293
12294 test_118f() {
12295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12296
12297         reset_async
12298
12299         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12300         lctl set_param fail_loc=0x8000040a
12301
12302         # Should simulate EINVAL error which is fatal
12303         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12304         RC=$?
12305         if [[ $RC -eq 0 ]]; then
12306                 error "Must return error due to dropped pages, rc=$RC"
12307         fi
12308
12309         lctl set_param fail_loc=0x0
12310
12311         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12312         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12313         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12314                     grep -c writeback)
12315         if [[ $LOCKED -ne 0 ]]; then
12316                 error "Locked pages remain in cache, locked=$LOCKED"
12317         fi
12318
12319         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12320                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12321         fi
12322
12323         rm -f $DIR/$tfile
12324         echo "No pages locked after fsync"
12325
12326         reset_async
12327         return 0
12328 }
12329 run_test 118f "Simulate unrecoverable OSC side error =========="
12330
12331 test_118g() {
12332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12333
12334         reset_async
12335
12336         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12337         lctl set_param fail_loc=0x406
12338
12339         # simulate local -ENOMEM
12340         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12341         RC=$?
12342
12343         lctl set_param fail_loc=0
12344         if [[ $RC -eq 0 ]]; then
12345                 error "Must return error due to dropped pages, rc=$RC"
12346         fi
12347
12348         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12349         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12350         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12351                         grep -c writeback)
12352         if [[ $LOCKED -ne 0 ]]; then
12353                 error "Locked pages remain in cache, locked=$LOCKED"
12354         fi
12355
12356         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12357                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12358         fi
12359
12360         rm -f $DIR/$tfile
12361         echo "No pages locked after fsync"
12362
12363         reset_async
12364         return 0
12365 }
12366 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12367
12368 test_118h() {
12369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12370         remote_ost_nodsh && skip "remote OST with nodsh"
12371
12372         reset_async
12373
12374         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12375         set_nodes_failloc "$(osts_nodes)" 0x20e
12376         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12377         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12378         RC=$?
12379
12380         set_nodes_failloc "$(osts_nodes)" 0
12381         if [[ $RC -eq 0 ]]; then
12382                 error "Must return error due to dropped pages, rc=$RC"
12383         fi
12384
12385         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12386         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12387         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12388                     grep -c writeback)
12389         if [[ $LOCKED -ne 0 ]]; then
12390                 error "Locked pages remain in cache, locked=$LOCKED"
12391         fi
12392
12393         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12394                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12395         fi
12396
12397         rm -f $DIR/$tfile
12398         echo "No pages locked after fsync"
12399
12400         return 0
12401 }
12402 run_test 118h "Verify timeout in handling recoverables errors  =========="
12403
12404 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12405
12406 test_118i() {
12407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12408         remote_ost_nodsh && skip "remote OST with nodsh"
12409
12410         reset_async
12411
12412         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12413         set_nodes_failloc "$(osts_nodes)" 0x20e
12414
12415         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12416         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12417         PID=$!
12418         sleep 5
12419         set_nodes_failloc "$(osts_nodes)" 0
12420
12421         wait $PID
12422         RC=$?
12423         if [[ $RC -ne 0 ]]; then
12424                 error "got error, but should be not, rc=$RC"
12425         fi
12426
12427         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12428         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12429         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12430         if [[ $LOCKED -ne 0 ]]; then
12431                 error "Locked pages remain in cache, locked=$LOCKED"
12432         fi
12433
12434         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12435                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12436         fi
12437
12438         rm -f $DIR/$tfile
12439         echo "No pages locked after fsync"
12440
12441         return 0
12442 }
12443 run_test 118i "Fix error before timeout in recoverable error  =========="
12444
12445 [ "$SLOW" = "no" ] && set_resend_count 4
12446
12447 test_118j() {
12448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12449         remote_ost_nodsh && skip "remote OST with nodsh"
12450
12451         reset_async
12452
12453         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12454         set_nodes_failloc "$(osts_nodes)" 0x220
12455
12456         # return -EIO from OST
12457         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12458         RC=$?
12459         set_nodes_failloc "$(osts_nodes)" 0x0
12460         if [[ $RC -eq 0 ]]; then
12461                 error "Must return error due to dropped pages, rc=$RC"
12462         fi
12463
12464         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12465         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12466         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12467         if [[ $LOCKED -ne 0 ]]; then
12468                 error "Locked pages remain in cache, locked=$LOCKED"
12469         fi
12470
12471         # in recoverable error on OST we want resend and stay until it finished
12472         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12473                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12474         fi
12475
12476         rm -f $DIR/$tfile
12477         echo "No pages locked after fsync"
12478
12479         return 0
12480 }
12481 run_test 118j "Simulate unrecoverable OST side error =========="
12482
12483 test_118k()
12484 {
12485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12486         remote_ost_nodsh && skip "remote OSTs with nodsh"
12487
12488         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12489         set_nodes_failloc "$(osts_nodes)" 0x20e
12490         test_mkdir $DIR/$tdir
12491
12492         for ((i=0;i<10;i++)); do
12493                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12494                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12495                 SLEEPPID=$!
12496                 sleep 0.500s
12497                 kill $SLEEPPID
12498                 wait $SLEEPPID
12499         done
12500
12501         set_nodes_failloc "$(osts_nodes)" 0
12502         rm -rf $DIR/$tdir
12503 }
12504 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12505
12506 test_118l() # LU-646
12507 {
12508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12509
12510         test_mkdir $DIR/$tdir
12511         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12512         rm -rf $DIR/$tdir
12513 }
12514 run_test 118l "fsync dir"
12515
12516 test_118m() # LU-3066
12517 {
12518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12519
12520         test_mkdir $DIR/$tdir
12521         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12522         rm -rf $DIR/$tdir
12523 }
12524 run_test 118m "fdatasync dir ========="
12525
12526 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12527
12528 test_118n()
12529 {
12530         local begin
12531         local end
12532
12533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12534         remote_ost_nodsh && skip "remote OSTs with nodsh"
12535
12536         # Sleep to avoid a cached response.
12537         #define OBD_STATFS_CACHE_SECONDS 1
12538         sleep 2
12539
12540         # Inject a 10 second delay in the OST_STATFS handler.
12541         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12542         set_nodes_failloc "$(osts_nodes)" 0x242
12543
12544         begin=$SECONDS
12545         stat --file-system $MOUNT > /dev/null
12546         end=$SECONDS
12547
12548         set_nodes_failloc "$(osts_nodes)" 0
12549
12550         if ((end - begin > 20)); then
12551             error "statfs took $((end - begin)) seconds, expected 10"
12552         fi
12553 }
12554 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12555
12556 test_119a() # bug 11737
12557 {
12558         BSIZE=$((512 * 1024))
12559         directio write $DIR/$tfile 0 1 $BSIZE
12560         # We ask to read two blocks, which is more than a file size.
12561         # directio will indicate an error when requested and actual
12562         # sizes aren't equeal (a normal situation in this case) and
12563         # print actual read amount.
12564         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12565         if [ "$NOB" != "$BSIZE" ]; then
12566                 error "read $NOB bytes instead of $BSIZE"
12567         fi
12568         rm -f $DIR/$tfile
12569 }
12570 run_test 119a "Short directIO read must return actual read amount"
12571
12572 test_119b() # bug 11737
12573 {
12574         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12575
12576         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12577         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12578         sync
12579         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12580                 error "direct read failed"
12581         rm -f $DIR/$tfile
12582 }
12583 run_test 119b "Sparse directIO read must return actual read amount"
12584
12585 test_119c() # bug 13099
12586 {
12587         BSIZE=1048576
12588         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12589         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12590         rm -f $DIR/$tfile
12591 }
12592 run_test 119c "Testing for direct read hitting hole"
12593
12594 test_119d() # bug 15950
12595 {
12596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12597
12598         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12599         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12600         BSIZE=1048576
12601         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12602         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12603         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12604         lctl set_param fail_loc=0x40d
12605         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12606         pid_dio=$!
12607         sleep 1
12608         cat $DIR/$tfile > /dev/null &
12609         lctl set_param fail_loc=0
12610         pid_reads=$!
12611         wait $pid_dio
12612         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12613         sleep 2
12614         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12615         error "the read rpcs have not completed in 2s"
12616         rm -f $DIR/$tfile
12617         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12618 }
12619 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12620
12621 test_120a() {
12622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12623         remote_mds_nodsh && skip "remote MDS with nodsh"
12624         test_mkdir -i0 -c1 $DIR/$tdir
12625         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12626                 skip_env "no early lock cancel on server"
12627
12628         lru_resize_disable mdc
12629         lru_resize_disable osc
12630         cancel_lru_locks mdc
12631         # asynchronous object destroy at MDT could cause bl ast to client
12632         cancel_lru_locks osc
12633
12634         stat $DIR/$tdir > /dev/null
12635         can1=$(do_facet mds1 \
12636                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12637                awk '/ldlm_cancel/ {print $2}')
12638         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12639                awk '/ldlm_bl_callback/ {print $2}')
12640         test_mkdir -i0 -c1 $DIR/$tdir/d1
12641         can2=$(do_facet mds1 \
12642                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12643                awk '/ldlm_cancel/ {print $2}')
12644         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12645                awk '/ldlm_bl_callback/ {print $2}')
12646         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12647         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12648         lru_resize_enable mdc
12649         lru_resize_enable osc
12650 }
12651 run_test 120a "Early Lock Cancel: mkdir test"
12652
12653 test_120b() {
12654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12655         remote_mds_nodsh && skip "remote MDS with nodsh"
12656         test_mkdir $DIR/$tdir
12657         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12658                 skip_env "no early lock cancel on server"
12659
12660         lru_resize_disable mdc
12661         lru_resize_disable osc
12662         cancel_lru_locks mdc
12663         stat $DIR/$tdir > /dev/null
12664         can1=$(do_facet $SINGLEMDS \
12665                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12666                awk '/ldlm_cancel/ {print $2}')
12667         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12668                awk '/ldlm_bl_callback/ {print $2}')
12669         touch $DIR/$tdir/f1
12670         can2=$(do_facet $SINGLEMDS \
12671                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12672                awk '/ldlm_cancel/ {print $2}')
12673         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12674                awk '/ldlm_bl_callback/ {print $2}')
12675         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12676         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12677         lru_resize_enable mdc
12678         lru_resize_enable osc
12679 }
12680 run_test 120b "Early Lock Cancel: create test"
12681
12682 test_120c() {
12683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12684         remote_mds_nodsh && skip "remote MDS with nodsh"
12685         test_mkdir -i0 -c1 $DIR/$tdir
12686         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12687                 skip "no early lock cancel on server"
12688
12689         lru_resize_disable mdc
12690         lru_resize_disable osc
12691         test_mkdir -i0 -c1 $DIR/$tdir/d1
12692         test_mkdir -i0 -c1 $DIR/$tdir/d2
12693         touch $DIR/$tdir/d1/f1
12694         cancel_lru_locks mdc
12695         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12696         can1=$(do_facet mds1 \
12697                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12698                awk '/ldlm_cancel/ {print $2}')
12699         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12700                awk '/ldlm_bl_callback/ {print $2}')
12701         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12702         can2=$(do_facet mds1 \
12703                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12704                awk '/ldlm_cancel/ {print $2}')
12705         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12706                awk '/ldlm_bl_callback/ {print $2}')
12707         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12708         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12709         lru_resize_enable mdc
12710         lru_resize_enable osc
12711 }
12712 run_test 120c "Early Lock Cancel: link test"
12713
12714 test_120d() {
12715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12716         remote_mds_nodsh && skip "remote MDS with nodsh"
12717         test_mkdir -i0 -c1 $DIR/$tdir
12718         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12719                 skip_env "no early lock cancel on server"
12720
12721         lru_resize_disable mdc
12722         lru_resize_disable osc
12723         touch $DIR/$tdir
12724         cancel_lru_locks mdc
12725         stat $DIR/$tdir > /dev/null
12726         can1=$(do_facet mds1 \
12727                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12728                awk '/ldlm_cancel/ {print $2}')
12729         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12730                awk '/ldlm_bl_callback/ {print $2}')
12731         chmod a+x $DIR/$tdir
12732         can2=$(do_facet mds1 \
12733                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12734                awk '/ldlm_cancel/ {print $2}')
12735         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12736                awk '/ldlm_bl_callback/ {print $2}')
12737         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12738         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12739         lru_resize_enable mdc
12740         lru_resize_enable osc
12741 }
12742 run_test 120d "Early Lock Cancel: setattr test"
12743
12744 test_120e() {
12745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12746         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12747                 skip_env "no early lock cancel on server"
12748         remote_mds_nodsh && skip "remote MDS with nodsh"
12749
12750         local dlmtrace_set=false
12751
12752         test_mkdir -i0 -c1 $DIR/$tdir
12753         lru_resize_disable mdc
12754         lru_resize_disable osc
12755         ! $LCTL get_param debug | grep -q dlmtrace &&
12756                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12757         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12758         cancel_lru_locks mdc
12759         cancel_lru_locks osc
12760         dd if=$DIR/$tdir/f1 of=/dev/null
12761         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12762         # XXX client can not do early lock cancel of OST lock
12763         # during unlink (LU-4206), so cancel osc lock now.
12764         sleep 2
12765         cancel_lru_locks osc
12766         can1=$(do_facet mds1 \
12767                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12768                awk '/ldlm_cancel/ {print $2}')
12769         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12770                awk '/ldlm_bl_callback/ {print $2}')
12771         unlink $DIR/$tdir/f1
12772         sleep 5
12773         can2=$(do_facet mds1 \
12774                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12775                awk '/ldlm_cancel/ {print $2}')
12776         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12777                awk '/ldlm_bl_callback/ {print $2}')
12778         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12779                 $LCTL dk $TMP/cancel.debug.txt
12780         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12781                 $LCTL dk $TMP/blocking.debug.txt
12782         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12783         lru_resize_enable mdc
12784         lru_resize_enable osc
12785 }
12786 run_test 120e "Early Lock Cancel: unlink test"
12787
12788 test_120f() {
12789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12790         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12791                 skip_env "no early lock cancel on server"
12792         remote_mds_nodsh && skip "remote MDS with nodsh"
12793
12794         test_mkdir -i0 -c1 $DIR/$tdir
12795         lru_resize_disable mdc
12796         lru_resize_disable osc
12797         test_mkdir -i0 -c1 $DIR/$tdir/d1
12798         test_mkdir -i0 -c1 $DIR/$tdir/d2
12799         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12800         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12801         cancel_lru_locks mdc
12802         cancel_lru_locks osc
12803         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12804         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12805         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12806         # XXX client can not do early lock cancel of OST lock
12807         # during rename (LU-4206), so cancel osc lock now.
12808         sleep 2
12809         cancel_lru_locks osc
12810         can1=$(do_facet mds1 \
12811                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12812                awk '/ldlm_cancel/ {print $2}')
12813         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12814                awk '/ldlm_bl_callback/ {print $2}')
12815         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12816         sleep 5
12817         can2=$(do_facet mds1 \
12818                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12819                awk '/ldlm_cancel/ {print $2}')
12820         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12821                awk '/ldlm_bl_callback/ {print $2}')
12822         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12823         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12824         lru_resize_enable mdc
12825         lru_resize_enable osc
12826 }
12827 run_test 120f "Early Lock Cancel: rename test"
12828
12829 test_120g() {
12830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12831         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12832                 skip_env "no early lock cancel on server"
12833         remote_mds_nodsh && skip "remote MDS with nodsh"
12834
12835         lru_resize_disable mdc
12836         lru_resize_disable osc
12837         count=10000
12838         echo create $count files
12839         test_mkdir $DIR/$tdir
12840         cancel_lru_locks mdc
12841         cancel_lru_locks osc
12842         t0=$(date +%s)
12843
12844         can0=$(do_facet $SINGLEMDS \
12845                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12846                awk '/ldlm_cancel/ {print $2}')
12847         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12848                awk '/ldlm_bl_callback/ {print $2}')
12849         createmany -o $DIR/$tdir/f $count
12850         sync
12851         can1=$(do_facet $SINGLEMDS \
12852                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12853                awk '/ldlm_cancel/ {print $2}')
12854         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12855                awk '/ldlm_bl_callback/ {print $2}')
12856         t1=$(date +%s)
12857         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12858         echo rm $count files
12859         rm -r $DIR/$tdir
12860         sync
12861         can2=$(do_facet $SINGLEMDS \
12862                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12863                awk '/ldlm_cancel/ {print $2}')
12864         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12865                awk '/ldlm_bl_callback/ {print $2}')
12866         t2=$(date +%s)
12867         echo total: $count removes in $((t2-t1))
12868         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12869         sleep 2
12870         # wait for commitment of removal
12871         lru_resize_enable mdc
12872         lru_resize_enable osc
12873 }
12874 run_test 120g "Early Lock Cancel: performance test"
12875
12876 test_121() { #bug #10589
12877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12878
12879         rm -rf $DIR/$tfile
12880         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12881 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12882         lctl set_param fail_loc=0x310
12883         cancel_lru_locks osc > /dev/null
12884         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12885         lctl set_param fail_loc=0
12886         [[ $reads -eq $writes ]] ||
12887                 error "read $reads blocks, must be $writes blocks"
12888 }
12889 run_test 121 "read cancel race ========="
12890
12891 test_123a_base() { # was test 123, statahead(bug 11401)
12892         local lsx="$1"
12893
12894         SLOWOK=0
12895         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12896                 log "testing UP system. Performance may be lower than expected."
12897                 SLOWOK=1
12898         fi
12899
12900         rm -rf $DIR/$tdir
12901         test_mkdir $DIR/$tdir
12902         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12903         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12904         MULT=10
12905         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12906                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12907
12908                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12909                 lctl set_param -n llite.*.statahead_max 0
12910                 lctl get_param llite.*.statahead_max
12911                 cancel_lru_locks mdc
12912                 cancel_lru_locks osc
12913                 stime=$(date +%s)
12914                 time $lsx $DIR/$tdir | wc -l
12915                 etime=$(date +%s)
12916                 delta=$((etime - stime))
12917                 log "$lsx $i files without statahead: $delta sec"
12918                 lctl set_param llite.*.statahead_max=$max
12919
12920                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12921                         grep "statahead wrong:" | awk '{print $3}')
12922                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12923                 cancel_lru_locks mdc
12924                 cancel_lru_locks osc
12925                 stime=$(date +%s)
12926                 time $lsx $DIR/$tdir | wc -l
12927                 etime=$(date +%s)
12928                 delta_sa=$((etime - stime))
12929                 log "$lsx $i files with statahead: $delta_sa sec"
12930                 lctl get_param -n llite.*.statahead_stats
12931                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12932                         grep "statahead wrong:" | awk '{print $3}')
12933
12934                 [[ $swrong -lt $ewrong ]] &&
12935                         log "statahead was stopped, maybe too many locks held!"
12936                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12937
12938                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12939                         max=$(lctl get_param -n llite.*.statahead_max |
12940                                 head -n 1)
12941                         lctl set_param -n llite.*.statahead_max 0
12942                         lctl get_param llite.*.statahead_max
12943                         cancel_lru_locks mdc
12944                         cancel_lru_locks osc
12945                         stime=$(date +%s)
12946                         time $lsx $DIR/$tdir | wc -l
12947                         etime=$(date +%s)
12948                         delta=$((etime - stime))
12949                         log "$lsx $i files again without statahead: $delta sec"
12950                         lctl set_param llite.*.statahead_max=$max
12951                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12952                                 if [  $SLOWOK -eq 0 ]; then
12953                                         error "$lsx $i files is slower with statahead!"
12954                                 else
12955                                         log "$lsx $i files is slower with statahead!"
12956                                 fi
12957                                 break
12958                         fi
12959                 fi
12960
12961                 [ $delta -gt 20 ] && break
12962                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12963                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12964         done
12965         log "$lsx done"
12966
12967         stime=$(date +%s)
12968         rm -r $DIR/$tdir
12969         sync
12970         etime=$(date +%s)
12971         delta=$((etime - stime))
12972         log "rm -r $DIR/$tdir/: $delta seconds"
12973         log "rm done"
12974         lctl get_param -n llite.*.statahead_stats
12975 }
12976
12977 test_123aa() {
12978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12979
12980         test_123a_base "ls -l"
12981 }
12982 run_test 123aa "verify statahead work"
12983
12984 test_123ab() {
12985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12986
12987         statx_supported || skip_env "Test must be statx() syscall supported"
12988
12989         test_123a_base "$STATX -l"
12990 }
12991 run_test 123ab "verify statahead work by using statx"
12992
12993 test_123ac() {
12994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12995
12996         statx_supported || skip_env "Test must be statx() syscall supported"
12997
12998         local rpcs_before
12999         local rpcs_after
13000         local agl_before
13001         local agl_after
13002
13003         cancel_lru_locks $OSC
13004         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13005         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13006                 awk '/agl.total:/ {print $3}')
13007         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13008         test_123a_base "$STATX --cached=always -D"
13009         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13010                 awk '/agl.total:/ {print $3}')
13011         [ $agl_before -eq $agl_after ] ||
13012                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13013         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13014         [ $rpcs_after -eq $rpcs_before ] ||
13015                 error "$STATX should not send glimpse RPCs to $OSC"
13016 }
13017 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13018
13019 test_123b () { # statahead(bug 15027)
13020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13021
13022         test_mkdir $DIR/$tdir
13023         createmany -o $DIR/$tdir/$tfile-%d 1000
13024
13025         cancel_lru_locks mdc
13026         cancel_lru_locks osc
13027
13028 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13029         lctl set_param fail_loc=0x80000803
13030         ls -lR $DIR/$tdir > /dev/null
13031         log "ls done"
13032         lctl set_param fail_loc=0x0
13033         lctl get_param -n llite.*.statahead_stats
13034         rm -r $DIR/$tdir
13035         sync
13036
13037 }
13038 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13039
13040 test_123c() {
13041         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13042
13043         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13044         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13045         touch $DIR/$tdir.1/{1..3}
13046         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13047
13048         remount_client $MOUNT
13049
13050         $MULTIOP $DIR/$tdir.0 Q
13051
13052         # let statahead to complete
13053         ls -l $DIR/$tdir.0 > /dev/null
13054
13055         testid=$(echo $TESTNAME | tr '_' ' ')
13056         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13057                 error "statahead warning" || true
13058 }
13059 run_test 123c "Can not initialize inode warning on DNE statahead"
13060
13061 test_124a() {
13062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13063         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13064                 skip_env "no lru resize on server"
13065
13066         local NR=2000
13067
13068         test_mkdir $DIR/$tdir
13069
13070         log "create $NR files at $DIR/$tdir"
13071         createmany -o $DIR/$tdir/f $NR ||
13072                 error "failed to create $NR files in $DIR/$tdir"
13073
13074         cancel_lru_locks mdc
13075         ls -l $DIR/$tdir > /dev/null
13076
13077         local NSDIR=""
13078         local LRU_SIZE=0
13079         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13080                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13081                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13082                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13083                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13084                         log "NSDIR=$NSDIR"
13085                         log "NS=$(basename $NSDIR)"
13086                         break
13087                 fi
13088         done
13089
13090         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13091                 skip "Not enough cached locks created!"
13092         fi
13093         log "LRU=$LRU_SIZE"
13094
13095         local SLEEP=30
13096
13097         # We know that lru resize allows one client to hold $LIMIT locks
13098         # for 10h. After that locks begin to be killed by client.
13099         local MAX_HRS=10
13100         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13101         log "LIMIT=$LIMIT"
13102         if [ $LIMIT -lt $LRU_SIZE ]; then
13103                 skip "Limit is too small $LIMIT"
13104         fi
13105
13106         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13107         # killing locks. Some time was spent for creating locks. This means
13108         # that up to the moment of sleep finish we must have killed some of
13109         # them (10-100 locks). This depends on how fast ther were created.
13110         # Many of them were touched in almost the same moment and thus will
13111         # be killed in groups.
13112         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13113
13114         # Use $LRU_SIZE_B here to take into account real number of locks
13115         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13116         local LRU_SIZE_B=$LRU_SIZE
13117         log "LVF=$LVF"
13118         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13119         log "OLD_LVF=$OLD_LVF"
13120         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13121
13122         # Let's make sure that we really have some margin. Client checks
13123         # cached locks every 10 sec.
13124         SLEEP=$((SLEEP+20))
13125         log "Sleep ${SLEEP} sec"
13126         local SEC=0
13127         while ((SEC<$SLEEP)); do
13128                 echo -n "..."
13129                 sleep 5
13130                 SEC=$((SEC+5))
13131                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13132                 echo -n "$LRU_SIZE"
13133         done
13134         echo ""
13135         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13136         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13137
13138         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13139                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13140                 unlinkmany $DIR/$tdir/f $NR
13141                 return
13142         }
13143
13144         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13145         log "unlink $NR files at $DIR/$tdir"
13146         unlinkmany $DIR/$tdir/f $NR
13147 }
13148 run_test 124a "lru resize ======================================="
13149
13150 get_max_pool_limit()
13151 {
13152         local limit=$($LCTL get_param \
13153                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13154         local max=0
13155         for l in $limit; do
13156                 if [[ $l -gt $max ]]; then
13157                         max=$l
13158                 fi
13159         done
13160         echo $max
13161 }
13162
13163 test_124b() {
13164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13165         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13166                 skip_env "no lru resize on server"
13167
13168         LIMIT=$(get_max_pool_limit)
13169
13170         NR=$(($(default_lru_size)*20))
13171         if [[ $NR -gt $LIMIT ]]; then
13172                 log "Limit lock number by $LIMIT locks"
13173                 NR=$LIMIT
13174         fi
13175
13176         IFree=$(mdsrate_inodes_available)
13177         if [ $IFree -lt $NR ]; then
13178                 log "Limit lock number by $IFree inodes"
13179                 NR=$IFree
13180         fi
13181
13182         lru_resize_disable mdc
13183         test_mkdir -p $DIR/$tdir/disable_lru_resize
13184
13185         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13186         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13187         cancel_lru_locks mdc
13188         stime=`date +%s`
13189         PID=""
13190         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13191         PID="$PID $!"
13192         sleep 2
13193         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13194         PID="$PID $!"
13195         sleep 2
13196         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13197         PID="$PID $!"
13198         wait $PID
13199         etime=`date +%s`
13200         nolruresize_delta=$((etime-stime))
13201         log "ls -la time: $nolruresize_delta seconds"
13202         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13203         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13204
13205         lru_resize_enable mdc
13206         test_mkdir -p $DIR/$tdir/enable_lru_resize
13207
13208         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13209         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13210         cancel_lru_locks mdc
13211         stime=`date +%s`
13212         PID=""
13213         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13214         PID="$PID $!"
13215         sleep 2
13216         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13217         PID="$PID $!"
13218         sleep 2
13219         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13220         PID="$PID $!"
13221         wait $PID
13222         etime=`date +%s`
13223         lruresize_delta=$((etime-stime))
13224         log "ls -la time: $lruresize_delta seconds"
13225         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13226
13227         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13228                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13229         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13230                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13231         else
13232                 log "lru resize performs the same with no lru resize"
13233         fi
13234         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13235 }
13236 run_test 124b "lru resize (performance test) ======================="
13237
13238 test_124c() {
13239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13240         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13241                 skip_env "no lru resize on server"
13242
13243         # cache ununsed locks on client
13244         local nr=100
13245         cancel_lru_locks mdc
13246         test_mkdir $DIR/$tdir
13247         createmany -o $DIR/$tdir/f $nr ||
13248                 error "failed to create $nr files in $DIR/$tdir"
13249         ls -l $DIR/$tdir > /dev/null
13250
13251         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13252         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13253         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13254         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13255         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13256
13257         # set lru_max_age to 1 sec
13258         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13259         echo "sleep $((recalc_p * 2)) seconds..."
13260         sleep $((recalc_p * 2))
13261
13262         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13263         # restore lru_max_age
13264         $LCTL set_param -n $nsdir.lru_max_age $max_age
13265         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13266         unlinkmany $DIR/$tdir/f $nr
13267 }
13268 run_test 124c "LRUR cancel very aged locks"
13269
13270 test_124d() {
13271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13272         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13273                 skip_env "no lru resize on server"
13274
13275         # cache ununsed locks on client
13276         local nr=100
13277
13278         lru_resize_disable mdc
13279         stack_trap "lru_resize_enable mdc" EXIT
13280
13281         cancel_lru_locks mdc
13282
13283         # asynchronous object destroy at MDT could cause bl ast to client
13284         test_mkdir $DIR/$tdir
13285         createmany -o $DIR/$tdir/f $nr ||
13286                 error "failed to create $nr files in $DIR/$tdir"
13287         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13288
13289         ls -l $DIR/$tdir > /dev/null
13290
13291         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13292         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13293         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13294         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13295
13296         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13297
13298         # set lru_max_age to 1 sec
13299         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13300         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13301
13302         echo "sleep $((recalc_p * 2)) seconds..."
13303         sleep $((recalc_p * 2))
13304
13305         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13306
13307         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13308 }
13309 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13310
13311 test_125() { # 13358
13312         $LCTL get_param -n llite.*.client_type | grep -q local ||
13313                 skip "must run as local client"
13314         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13315                 skip_env "must have acl enabled"
13316         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13317
13318         test_mkdir $DIR/$tdir
13319         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13320         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13321         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13322 }
13323 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13324
13325 test_126() { # bug 12829/13455
13326         $GSS && skip_env "must run as gss disabled"
13327         $LCTL get_param -n llite.*.client_type | grep -q local ||
13328                 skip "must run as local client"
13329         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13330
13331         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13332         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13333         rm -f $DIR/$tfile
13334         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13335 }
13336 run_test 126 "check that the fsgid provided by the client is taken into account"
13337
13338 test_127a() { # bug 15521
13339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13340         local name count samp unit min max sum sumsq
13341
13342         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13343         echo "stats before reset"
13344         $LCTL get_param osc.*.stats
13345         $LCTL set_param osc.*.stats=0
13346         local fsize=$((2048 * 1024))
13347
13348         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13349         cancel_lru_locks osc
13350         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13351
13352         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13353         stack_trap "rm -f $TMP/$tfile.tmp"
13354         while read name count samp unit min max sum sumsq; do
13355                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13356                 [ ! $min ] && error "Missing min value for $name proc entry"
13357                 eval $name=$count || error "Wrong proc format"
13358
13359                 case $name in
13360                 read_bytes|write_bytes)
13361                         [[ "$unit" =~ "bytes" ]] ||
13362                                 error "unit is not 'bytes': $unit"
13363                         (( $min >= 4096 )) || error "min is too small: $min"
13364                         (( $min <= $fsize )) || error "min is too big: $min"
13365                         (( $max >= 4096 )) || error "max is too small: $max"
13366                         (( $max <= $fsize )) || error "max is too big: $max"
13367                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13368                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13369                                 error "sumsquare is too small: $sumsq"
13370                         (( $sumsq <= $fsize * $fsize )) ||
13371                                 error "sumsquare is too big: $sumsq"
13372                         ;;
13373                 ost_read|ost_write)
13374                         [[ "$unit" =~ "usec" ]] ||
13375                                 error "unit is not 'usec': $unit"
13376                         ;;
13377                 *)      ;;
13378                 esac
13379         done < $DIR/$tfile.tmp
13380
13381         #check that we actually got some stats
13382         [ "$read_bytes" ] || error "Missing read_bytes stats"
13383         [ "$write_bytes" ] || error "Missing write_bytes stats"
13384         [ "$read_bytes" != 0 ] || error "no read done"
13385         [ "$write_bytes" != 0 ] || error "no write done"
13386 }
13387 run_test 127a "verify the client stats are sane"
13388
13389 test_127b() { # bug LU-333
13390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13391         local name count samp unit min max sum sumsq
13392
13393         echo "stats before reset"
13394         $LCTL get_param llite.*.stats
13395         $LCTL set_param llite.*.stats=0
13396
13397         # perform 2 reads and writes so MAX is different from SUM.
13398         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13399         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13400         cancel_lru_locks osc
13401         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13402         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13403
13404         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13405         stack_trap "rm -f $TMP/$tfile.tmp"
13406         while read name count samp unit min max sum sumsq; do
13407                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13408                 eval $name=$count || error "Wrong proc format"
13409
13410                 case $name in
13411                 read_bytes|write_bytes)
13412                         [[ "$unit" =~ "bytes" ]] ||
13413                                 error "unit is not 'bytes': $unit"
13414                         (( $count == 2 )) || error "count is not 2: $count"
13415                         (( $min == $PAGE_SIZE )) ||
13416                                 error "min is not $PAGE_SIZE: $min"
13417                         (( $max == $PAGE_SIZE )) ||
13418                                 error "max is not $PAGE_SIZE: $max"
13419                         (( $sum == $PAGE_SIZE * 2 )) ||
13420                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13421                         ;;
13422                 read|write)
13423                         [[ "$unit" =~ "usec" ]] ||
13424                                 error "unit is not 'usec': $unit"
13425                         ;;
13426                 *)      ;;
13427                 esac
13428         done < $TMP/$tfile.tmp
13429
13430         #check that we actually got some stats
13431         [ "$read_bytes" ] || error "Missing read_bytes stats"
13432         [ "$write_bytes" ] || error "Missing write_bytes stats"
13433         [ "$read_bytes" != 0 ] || error "no read done"
13434         [ "$write_bytes" != 0 ] || error "no write done"
13435 }
13436 run_test 127b "verify the llite client stats are sane"
13437
13438 test_127c() { # LU-12394
13439         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13440         local size
13441         local bsize
13442         local reads
13443         local writes
13444         local count
13445
13446         $LCTL set_param llite.*.extents_stats=1
13447         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13448
13449         # Use two stripes so there is enough space in default config
13450         $LFS setstripe -c 2 $DIR/$tfile
13451
13452         # Extent stats start at 0-4K and go in power of two buckets
13453         # LL_HIST_START = 12 --> 2^12 = 4K
13454         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13455         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13456         # small configs
13457         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13458                 do
13459                 # Write and read, 2x each, second time at a non-zero offset
13460                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13461                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13462                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13463                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13464                 rm -f $DIR/$tfile
13465         done
13466
13467         $LCTL get_param llite.*.extents_stats
13468
13469         count=2
13470         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13471                 do
13472                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13473                                 grep -m 1 $bsize)
13474                 reads=$(echo $bucket | awk '{print $5}')
13475                 writes=$(echo $bucket | awk '{print $9}')
13476                 [ "$reads" -eq $count ] ||
13477                         error "$reads reads in < $bsize bucket, expect $count"
13478                 [ "$writes" -eq $count ] ||
13479                         error "$writes writes in < $bsize bucket, expect $count"
13480         done
13481
13482         # Test mmap write and read
13483         $LCTL set_param llite.*.extents_stats=c
13484         size=512
13485         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13486         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13487         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13488
13489         $LCTL get_param llite.*.extents_stats
13490
13491         count=$(((size*1024) / PAGE_SIZE))
13492
13493         bsize=$((2 * PAGE_SIZE / 1024))K
13494
13495         bucket=$($LCTL get_param -n llite.*.extents_stats |
13496                         grep -m 1 $bsize)
13497         reads=$(echo $bucket | awk '{print $5}')
13498         writes=$(echo $bucket | awk '{print $9}')
13499         # mmap writes fault in the page first, creating an additonal read
13500         [ "$reads" -eq $((2 * count)) ] ||
13501                 error "$reads reads in < $bsize bucket, expect $count"
13502         [ "$writes" -eq $count ] ||
13503                 error "$writes writes in < $bsize bucket, expect $count"
13504 }
13505 run_test 127c "test llite extent stats with regular & mmap i/o"
13506
13507 test_128() { # bug 15212
13508         touch $DIR/$tfile
13509         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13510                 find $DIR/$tfile
13511                 find $DIR/$tfile
13512         EOF
13513
13514         result=$(grep error $TMP/$tfile.log)
13515         rm -f $DIR/$tfile $TMP/$tfile.log
13516         [ -z "$result" ] ||
13517                 error "consecutive find's under interactive lfs failed"
13518 }
13519 run_test 128 "interactive lfs for 2 consecutive find's"
13520
13521 set_dir_limits () {
13522         local mntdev
13523         local canondev
13524         local node
13525
13526         local ldproc=/proc/fs/ldiskfs
13527         local facets=$(get_facets MDS)
13528
13529         for facet in ${facets//,/ }; do
13530                 canondev=$(ldiskfs_canon \
13531                            *.$(convert_facet2label $facet).mntdev $facet)
13532                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13533                         ldproc=/sys/fs/ldiskfs
13534                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13535                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13536         done
13537 }
13538
13539 check_mds_dmesg() {
13540         local facets=$(get_facets MDS)
13541         for facet in ${facets//,/ }; do
13542                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13543         done
13544         return 1
13545 }
13546
13547 test_129() {
13548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13549         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13550                 skip "Need MDS version with at least 2.5.56"
13551         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13552                 skip_env "ldiskfs only test"
13553         fi
13554         remote_mds_nodsh && skip "remote MDS with nodsh"
13555
13556         local ENOSPC=28
13557         local has_warning=false
13558
13559         rm -rf $DIR/$tdir
13560         mkdir -p $DIR/$tdir
13561
13562         # block size of mds1
13563         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13564         set_dir_limits $maxsize $((maxsize * 6 / 8))
13565         stack_trap "set_dir_limits 0 0"
13566         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13567         local dirsize=$(stat -c%s "$DIR/$tdir")
13568         local nfiles=0
13569         while (( $dirsize <= $maxsize )); do
13570                 $MCREATE $DIR/$tdir/file_base_$nfiles
13571                 rc=$?
13572                 # check two errors:
13573                 # ENOSPC for ext4 max_dir_size, which has been used since
13574                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13575                 if (( rc == ENOSPC )); then
13576                         set_dir_limits 0 0
13577                         echo "rc=$rc returned as expected after $nfiles files"
13578
13579                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13580                                 error "create failed w/o dir size limit"
13581
13582                         # messages may be rate limited if test is run repeatedly
13583                         check_mds_dmesg '"is approaching max"' ||
13584                                 echo "warning message should be output"
13585                         check_mds_dmesg '"has reached max"' ||
13586                                 echo "reached message should be output"
13587
13588                         dirsize=$(stat -c%s "$DIR/$tdir")
13589
13590                         [[ $dirsize -ge $maxsize ]] && return 0
13591                         error "dirsize $dirsize < $maxsize after $nfiles files"
13592                 elif (( rc != 0 )); then
13593                         break
13594                 fi
13595                 nfiles=$((nfiles + 1))
13596                 dirsize=$(stat -c%s "$DIR/$tdir")
13597         done
13598
13599         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13600 }
13601 run_test 129 "test directory size limit ========================"
13602
13603 OLDIFS="$IFS"
13604 cleanup_130() {
13605         trap 0
13606         IFS="$OLDIFS"
13607 }
13608
13609 test_130a() {
13610         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13611         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13612
13613         trap cleanup_130 EXIT RETURN
13614
13615         local fm_file=$DIR/$tfile
13616         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13617         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13618                 error "dd failed for $fm_file"
13619
13620         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13621         filefrag -ves $fm_file
13622         RC=$?
13623         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13624                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13625         [ $RC != 0 ] && error "filefrag $fm_file failed"
13626
13627         filefrag_op=$(filefrag -ve -k $fm_file |
13628                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13629         lun=$($LFS getstripe -i $fm_file)
13630
13631         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13632         IFS=$'\n'
13633         tot_len=0
13634         for line in $filefrag_op
13635         do
13636                 frag_lun=`echo $line | cut -d: -f5`
13637                 ext_len=`echo $line | cut -d: -f4`
13638                 if (( $frag_lun != $lun )); then
13639                         cleanup_130
13640                         error "FIEMAP on 1-stripe file($fm_file) failed"
13641                         return
13642                 fi
13643                 (( tot_len += ext_len ))
13644         done
13645
13646         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13647                 cleanup_130
13648                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13649                 return
13650         fi
13651
13652         cleanup_130
13653
13654         echo "FIEMAP on single striped file succeeded"
13655 }
13656 run_test 130a "FIEMAP (1-stripe file)"
13657
13658 test_130b() {
13659         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13660
13661         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13662         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13663
13664         trap cleanup_130 EXIT RETURN
13665
13666         local fm_file=$DIR/$tfile
13667         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13668                         error "setstripe on $fm_file"
13669         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13670                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13671
13672         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13673                 error "dd failed on $fm_file"
13674
13675         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13676         filefrag_op=$(filefrag -ve -k $fm_file |
13677                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13678
13679         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13680                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13681
13682         IFS=$'\n'
13683         tot_len=0
13684         num_luns=1
13685         for line in $filefrag_op
13686         do
13687                 frag_lun=$(echo $line | cut -d: -f5 |
13688                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13689                 ext_len=$(echo $line | cut -d: -f4)
13690                 if (( $frag_lun != $last_lun )); then
13691                         if (( tot_len != 1024 )); then
13692                                 cleanup_130
13693                                 error "FIEMAP on $fm_file failed; returned " \
13694                                 "len $tot_len for OST $last_lun instead of 1024"
13695                                 return
13696                         else
13697                                 (( num_luns += 1 ))
13698                                 tot_len=0
13699                         fi
13700                 fi
13701                 (( tot_len += ext_len ))
13702                 last_lun=$frag_lun
13703         done
13704         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13705                 cleanup_130
13706                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13707                         "luns or wrong len for OST $last_lun"
13708                 return
13709         fi
13710
13711         cleanup_130
13712
13713         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13714 }
13715 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13716
13717 test_130c() {
13718         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13719
13720         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13721         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13722
13723         trap cleanup_130 EXIT RETURN
13724
13725         local fm_file=$DIR/$tfile
13726         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13727         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13728                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13729
13730         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13731                         error "dd failed on $fm_file"
13732
13733         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13734         filefrag_op=$(filefrag -ve -k $fm_file |
13735                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13736
13737         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13738                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13739
13740         IFS=$'\n'
13741         tot_len=0
13742         num_luns=1
13743         for line in $filefrag_op
13744         do
13745                 frag_lun=$(echo $line | cut -d: -f5 |
13746                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13747                 ext_len=$(echo $line | cut -d: -f4)
13748                 if (( $frag_lun != $last_lun )); then
13749                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13750                         if (( logical != 512 )); then
13751                                 cleanup_130
13752                                 error "FIEMAP on $fm_file failed; returned " \
13753                                 "logical start for lun $logical instead of 512"
13754                                 return
13755                         fi
13756                         if (( tot_len != 512 )); then
13757                                 cleanup_130
13758                                 error "FIEMAP on $fm_file failed; returned " \
13759                                 "len $tot_len for OST $last_lun instead of 1024"
13760                                 return
13761                         else
13762                                 (( num_luns += 1 ))
13763                                 tot_len=0
13764                         fi
13765                 fi
13766                 (( tot_len += ext_len ))
13767                 last_lun=$frag_lun
13768         done
13769         if (( num_luns != 2 || tot_len != 512 )); then
13770                 cleanup_130
13771                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13772                         "luns or wrong len for OST $last_lun"
13773                 return
13774         fi
13775
13776         cleanup_130
13777
13778         echo "FIEMAP on 2-stripe file with hole succeeded"
13779 }
13780 run_test 130c "FIEMAP (2-stripe file with hole)"
13781
13782 test_130d() {
13783         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13784
13785         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13786         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13787
13788         trap cleanup_130 EXIT RETURN
13789
13790         local fm_file=$DIR/$tfile
13791         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13792                         error "setstripe on $fm_file"
13793         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13794                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13795
13796         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13797         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13798                 error "dd failed on $fm_file"
13799
13800         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13801         filefrag_op=$(filefrag -ve -k $fm_file |
13802                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13803
13804         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13805                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13806
13807         IFS=$'\n'
13808         tot_len=0
13809         num_luns=1
13810         for line in $filefrag_op
13811         do
13812                 frag_lun=$(echo $line | cut -d: -f5 |
13813                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13814                 ext_len=$(echo $line | cut -d: -f4)
13815                 if (( $frag_lun != $last_lun )); then
13816                         if (( tot_len != 1024 )); then
13817                                 cleanup_130
13818                                 error "FIEMAP on $fm_file failed; returned " \
13819                                 "len $tot_len for OST $last_lun instead of 1024"
13820                                 return
13821                         else
13822                                 (( num_luns += 1 ))
13823                                 tot_len=0
13824                         fi
13825                 fi
13826                 (( tot_len += ext_len ))
13827                 last_lun=$frag_lun
13828         done
13829         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13830                 cleanup_130
13831                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13832                         "luns or wrong len for OST $last_lun"
13833                 return
13834         fi
13835
13836         cleanup_130
13837
13838         echo "FIEMAP on N-stripe file succeeded"
13839 }
13840 run_test 130d "FIEMAP (N-stripe file)"
13841
13842 test_130e() {
13843         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13844
13845         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13846         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13847
13848         trap cleanup_130 EXIT RETURN
13849
13850         local fm_file=$DIR/$tfile
13851         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13852
13853         NUM_BLKS=512
13854         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13855         for ((i = 0; i < $NUM_BLKS; i++)); do
13856                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13857                         conv=notrunc > /dev/null 2>&1
13858         done
13859
13860         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13861         filefrag_op=$(filefrag -ve -k $fm_file |
13862                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13863
13864         last_lun=$(echo $filefrag_op | cut -d: -f5)
13865
13866         IFS=$'\n'
13867         tot_len=0
13868         num_luns=1
13869         for line in $filefrag_op; do
13870                 frag_lun=$(echo $line | cut -d: -f5)
13871                 ext_len=$(echo $line | cut -d: -f4)
13872                 if [[ "$frag_lun" != "$last_lun" ]]; then
13873                         if (( tot_len != $EXPECTED_LEN )); then
13874                                 cleanup_130
13875                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13876                         else
13877                                 (( num_luns += 1 ))
13878                                 tot_len=0
13879                         fi
13880                 fi
13881                 (( tot_len += ext_len ))
13882                 last_lun=$frag_lun
13883         done
13884         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13885                 cleanup_130
13886                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13887         fi
13888
13889         echo "FIEMAP with continuation calls succeeded"
13890 }
13891 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13892
13893 test_130f() {
13894         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13895         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13896
13897         local fm_file=$DIR/$tfile
13898         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13899                 error "multiop create with lov_delay_create on $fm_file"
13900
13901         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13902         filefrag_extents=$(filefrag -vek $fm_file |
13903                            awk '/extents? found/ { print $2 }')
13904         if [[ "$filefrag_extents" != "0" ]]; then
13905                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13906         fi
13907
13908         rm -f $fm_file
13909 }
13910 run_test 130f "FIEMAP (unstriped file)"
13911
13912 test_130g() {
13913         local file=$DIR/$tfile
13914         local nr=$((OSTCOUNT * 100))
13915
13916         $LFS setstripe -C $nr $file ||
13917                 error "failed to setstripe -C $nr $file"
13918
13919         dd if=/dev/zero of=$file count=$nr bs=1M
13920         sync
13921         nr=$($LFS getstripe -c $file)
13922
13923         local extents=$(filefrag -v $file |
13924                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13925
13926         echo "filefrag list $extents extents in file with stripecount $nr"
13927         if (( extents < nr )); then
13928                 $LFS getstripe $file
13929                 filefrag -v $file
13930                 error "filefrag printed $extents < $nr extents"
13931         fi
13932
13933         rm -f $file
13934 }
13935 run_test 130g "FIEMAP (overstripe file)"
13936
13937 # Test for writev/readv
13938 test_131a() {
13939         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13940                 error "writev test failed"
13941         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13942                 error "readv failed"
13943         rm -f $DIR/$tfile
13944 }
13945 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13946
13947 test_131b() {
13948         local fsize=$((524288 + 1048576 + 1572864))
13949         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13950                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13951                         error "append writev test failed"
13952
13953         ((fsize += 1572864 + 1048576))
13954         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13955                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13956                         error "append writev test failed"
13957         rm -f $DIR/$tfile
13958 }
13959 run_test 131b "test append writev"
13960
13961 test_131c() {
13962         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13963         error "NOT PASS"
13964 }
13965 run_test 131c "test read/write on file w/o objects"
13966
13967 test_131d() {
13968         rwv -f $DIR/$tfile -w -n 1 1572864
13969         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13970         if [ "$NOB" != 1572864 ]; then
13971                 error "Short read filed: read $NOB bytes instead of 1572864"
13972         fi
13973         rm -f $DIR/$tfile
13974 }
13975 run_test 131d "test short read"
13976
13977 test_131e() {
13978         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13979         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13980         error "read hitting hole failed"
13981         rm -f $DIR/$tfile
13982 }
13983 run_test 131e "test read hitting hole"
13984
13985 check_stats() {
13986         local facet=$1
13987         local op=$2
13988         local want=${3:-0}
13989         local res
13990
13991         case $facet in
13992         mds*) res=$(do_facet $facet \
13993                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13994                  ;;
13995         ost*) res=$(do_facet $facet \
13996                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13997                  ;;
13998         *) error "Wrong facet '$facet'" ;;
13999         esac
14000         [ "$res" ] || error "The counter for $op on $facet was not incremented"
14001         # if the argument $3 is zero, it means any stat increment is ok.
14002         if [[ $want -gt 0 ]]; then
14003                 local count=$(echo $res | awk '{ print $2 }')
14004                 [[ $count -ne $want ]] &&
14005                         error "The $op counter on $facet is $count, not $want"
14006         fi
14007 }
14008
14009 test_133a() {
14010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14011         remote_ost_nodsh && skip "remote OST with nodsh"
14012         remote_mds_nodsh && skip "remote MDS with nodsh"
14013         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14014                 skip_env "MDS doesn't support rename stats"
14015
14016         local testdir=$DIR/${tdir}/stats_testdir
14017
14018         mkdir -p $DIR/${tdir}
14019
14020         # clear stats.
14021         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14022         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14023
14024         # verify mdt stats first.
14025         mkdir ${testdir} || error "mkdir failed"
14026         check_stats $SINGLEMDS "mkdir" 1
14027         touch ${testdir}/${tfile} || error "touch failed"
14028         check_stats $SINGLEMDS "open" 1
14029         check_stats $SINGLEMDS "close" 1
14030         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14031                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14032                 check_stats $SINGLEMDS "mknod" 2
14033         }
14034         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14035         check_stats $SINGLEMDS "unlink" 1
14036         rm -f ${testdir}/${tfile} || error "file remove failed"
14037         check_stats $SINGLEMDS "unlink" 2
14038
14039         # remove working dir and check mdt stats again.
14040         rmdir ${testdir} || error "rmdir failed"
14041         check_stats $SINGLEMDS "rmdir" 1
14042
14043         local testdir1=$DIR/${tdir}/stats_testdir1
14044         mkdir -p ${testdir}
14045         mkdir -p ${testdir1}
14046         touch ${testdir1}/test1
14047         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14048         check_stats $SINGLEMDS "crossdir_rename" 1
14049
14050         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14051         check_stats $SINGLEMDS "samedir_rename" 1
14052
14053         rm -rf $DIR/${tdir}
14054 }
14055 run_test 133a "Verifying MDT stats ========================================"
14056
14057 test_133b() {
14058         local res
14059
14060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14061         remote_ost_nodsh && skip "remote OST with nodsh"
14062         remote_mds_nodsh && skip "remote MDS with nodsh"
14063
14064         local testdir=$DIR/${tdir}/stats_testdir
14065
14066         mkdir -p ${testdir} || error "mkdir failed"
14067         touch ${testdir}/${tfile} || error "touch failed"
14068         cancel_lru_locks mdc
14069
14070         # clear stats.
14071         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14072         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14073
14074         # extra mdt stats verification.
14075         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14076         check_stats $SINGLEMDS "setattr" 1
14077         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14078         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14079         then            # LU-1740
14080                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14081                 check_stats $SINGLEMDS "getattr" 1
14082         fi
14083         rm -rf $DIR/${tdir}
14084
14085         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14086         # so the check below is not reliable
14087         [ $MDSCOUNT -eq 1 ] || return 0
14088
14089         # Sleep to avoid a cached response.
14090         #define OBD_STATFS_CACHE_SECONDS 1
14091         sleep 2
14092         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14093         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14094         $LFS df || error "lfs failed"
14095         check_stats $SINGLEMDS "statfs" 1
14096
14097         # check aggregated statfs (LU-10018)
14098         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14099                 return 0
14100         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14101                 return 0
14102         sleep 2
14103         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14104         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14105         df $DIR
14106         check_stats $SINGLEMDS "statfs" 1
14107
14108         # We want to check that the client didn't send OST_STATFS to
14109         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14110         # extra care is needed here.
14111         if remote_mds; then
14112                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14113                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14114
14115                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14116                 [ "$res" ] && error "OST got STATFS"
14117         fi
14118
14119         return 0
14120 }
14121 run_test 133b "Verifying extra MDT stats =================================="
14122
14123 test_133c() {
14124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14125         remote_ost_nodsh && skip "remote OST with nodsh"
14126         remote_mds_nodsh && skip "remote MDS with nodsh"
14127
14128         local testdir=$DIR/$tdir/stats_testdir
14129
14130         test_mkdir -p $testdir
14131
14132         # verify obdfilter stats.
14133         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14134         sync
14135         cancel_lru_locks osc
14136         wait_delete_completed
14137
14138         # clear stats.
14139         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14140         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14141
14142         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14143                 error "dd failed"
14144         sync
14145         cancel_lru_locks osc
14146         check_stats ost1 "write" 1
14147
14148         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14149         check_stats ost1 "read" 1
14150
14151         > $testdir/$tfile || error "truncate failed"
14152         check_stats ost1 "punch" 1
14153
14154         rm -f $testdir/$tfile || error "file remove failed"
14155         wait_delete_completed
14156         check_stats ost1 "destroy" 1
14157
14158         rm -rf $DIR/$tdir
14159 }
14160 run_test 133c "Verifying OST stats ========================================"
14161
14162 order_2() {
14163         local value=$1
14164         local orig=$value
14165         local order=1
14166
14167         while [ $value -ge 2 ]; do
14168                 order=$((order*2))
14169                 value=$((value/2))
14170         done
14171
14172         if [ $orig -gt $order ]; then
14173                 order=$((order*2))
14174         fi
14175         echo $order
14176 }
14177
14178 size_in_KMGT() {
14179     local value=$1
14180     local size=('K' 'M' 'G' 'T');
14181     local i=0
14182     local size_string=$value
14183
14184     while [ $value -ge 1024 ]; do
14185         if [ $i -gt 3 ]; then
14186             #T is the biggest unit we get here, if that is bigger,
14187             #just return XXXT
14188             size_string=${value}T
14189             break
14190         fi
14191         value=$((value >> 10))
14192         if [ $value -lt 1024 ]; then
14193             size_string=${value}${size[$i]}
14194             break
14195         fi
14196         i=$((i + 1))
14197     done
14198
14199     echo $size_string
14200 }
14201
14202 get_rename_size() {
14203         local size=$1
14204         local context=${2:-.}
14205         local sample=$(do_facet $SINGLEMDS $LCTL \
14206                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14207                 grep -A1 $context |
14208                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14209         echo $sample
14210 }
14211
14212 test_133d() {
14213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14214         remote_ost_nodsh && skip "remote OST with nodsh"
14215         remote_mds_nodsh && skip "remote MDS with nodsh"
14216         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14217                 skip_env "MDS doesn't support rename stats"
14218
14219         local testdir1=$DIR/${tdir}/stats_testdir1
14220         local testdir2=$DIR/${tdir}/stats_testdir2
14221         mkdir -p $DIR/${tdir}
14222
14223         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14224
14225         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14226         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14227
14228         createmany -o $testdir1/test 512 || error "createmany failed"
14229
14230         # check samedir rename size
14231         mv ${testdir1}/test0 ${testdir1}/test_0
14232
14233         local testdir1_size=$(ls -l $DIR/${tdir} |
14234                 awk '/stats_testdir1/ {print $5}')
14235         local testdir2_size=$(ls -l $DIR/${tdir} |
14236                 awk '/stats_testdir2/ {print $5}')
14237
14238         testdir1_size=$(order_2 $testdir1_size)
14239         testdir2_size=$(order_2 $testdir2_size)
14240
14241         testdir1_size=$(size_in_KMGT $testdir1_size)
14242         testdir2_size=$(size_in_KMGT $testdir2_size)
14243
14244         echo "source rename dir size: ${testdir1_size}"
14245         echo "target rename dir size: ${testdir2_size}"
14246
14247         local cmd="do_facet $SINGLEMDS $LCTL "
14248         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14249
14250         eval $cmd || error "$cmd failed"
14251         local samedir=$($cmd | grep 'same_dir')
14252         local same_sample=$(get_rename_size $testdir1_size)
14253         [ -z "$samedir" ] && error "samedir_rename_size count error"
14254         [[ $same_sample -eq 1 ]] ||
14255                 error "samedir_rename_size error $same_sample"
14256         echo "Check same dir rename stats success"
14257
14258         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14259
14260         # check crossdir rename size
14261         mv ${testdir1}/test_0 ${testdir2}/test_0
14262
14263         testdir1_size=$(ls -l $DIR/${tdir} |
14264                 awk '/stats_testdir1/ {print $5}')
14265         testdir2_size=$(ls -l $DIR/${tdir} |
14266                 awk '/stats_testdir2/ {print $5}')
14267
14268         testdir1_size=$(order_2 $testdir1_size)
14269         testdir2_size=$(order_2 $testdir2_size)
14270
14271         testdir1_size=$(size_in_KMGT $testdir1_size)
14272         testdir2_size=$(size_in_KMGT $testdir2_size)
14273
14274         echo "source rename dir size: ${testdir1_size}"
14275         echo "target rename dir size: ${testdir2_size}"
14276
14277         eval $cmd || error "$cmd failed"
14278         local crossdir=$($cmd | grep 'crossdir')
14279         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14280         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14281         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14282         [[ $src_sample -eq 1 ]] ||
14283                 error "crossdir_rename_size error $src_sample"
14284         [[ $tgt_sample -eq 1 ]] ||
14285                 error "crossdir_rename_size error $tgt_sample"
14286         echo "Check cross dir rename stats success"
14287         rm -rf $DIR/${tdir}
14288 }
14289 run_test 133d "Verifying rename_stats ========================================"
14290
14291 test_133e() {
14292         remote_mds_nodsh && skip "remote MDS with nodsh"
14293         remote_ost_nodsh && skip "remote OST with nodsh"
14294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14295
14296         local testdir=$DIR/${tdir}/stats_testdir
14297         local ctr f0 f1 bs=32768 count=42 sum
14298
14299         mkdir -p ${testdir} || error "mkdir failed"
14300
14301         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14302
14303         for ctr in {write,read}_bytes; do
14304                 sync
14305                 cancel_lru_locks osc
14306
14307                 do_facet ost1 $LCTL set_param -n \
14308                         "obdfilter.*.exports.clear=clear"
14309
14310                 if [ $ctr = write_bytes ]; then
14311                         f0=/dev/zero
14312                         f1=${testdir}/${tfile}
14313                 else
14314                         f0=${testdir}/${tfile}
14315                         f1=/dev/null
14316                 fi
14317
14318                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14319                         error "dd failed"
14320                 sync
14321                 cancel_lru_locks osc
14322
14323                 sum=$(do_facet ost1 $LCTL get_param \
14324                         "obdfilter.*.exports.*.stats" |
14325                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14326                                 $1 == ctr { sum += $7 }
14327                                 END { printf("%0.0f", sum) }')
14328
14329                 if ((sum != bs * count)); then
14330                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14331                 fi
14332         done
14333
14334         rm -rf $DIR/${tdir}
14335 }
14336 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14337
14338 test_133f() {
14339         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14340                 skip "too old lustre for get_param -R ($facet_ver)"
14341
14342         # verifying readability.
14343         $LCTL get_param -R '*' &> /dev/null
14344
14345         # Verifing writability with badarea_io.
14346         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14347         local skipped_params='force_lbug|changelog_mask|daemon_file'
14348         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14349                 egrep -v "$skipped_params" |
14350                 xargs -n 1 find $proc_dirs -name |
14351                 xargs -n 1 badarea_io ||
14352                 error "client badarea_io failed"
14353
14354         # remount the FS in case writes/reads /proc break the FS
14355         cleanup || error "failed to unmount"
14356         setup || error "failed to setup"
14357 }
14358 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14359
14360 test_133g() {
14361         remote_mds_nodsh && skip "remote MDS with nodsh"
14362         remote_ost_nodsh && skip "remote OST with nodsh"
14363
14364         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14365         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14366         local facet
14367         for facet in mds1 ost1; do
14368                 local facet_ver=$(lustre_version_code $facet)
14369                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14370                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14371                 else
14372                         log "$facet: too old lustre for get_param -R"
14373                 fi
14374                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14375                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14376                                 tr -d = | egrep -v $skipped_params |
14377                                 xargs -n 1 find $proc_dirs -name |
14378                                 xargs -n 1 badarea_io" ||
14379                                         error "$facet badarea_io failed"
14380                 else
14381                         skip_noexit "$facet: too old lustre for get_param -R"
14382                 fi
14383         done
14384
14385         # remount the FS in case writes/reads /proc break the FS
14386         cleanup || error "failed to unmount"
14387         setup || error "failed to setup"
14388 }
14389 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14390
14391 test_133h() {
14392         remote_mds_nodsh && skip "remote MDS with nodsh"
14393         remote_ost_nodsh && skip "remote OST with nodsh"
14394         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14395                 skip "Need MDS version at least 2.9.54"
14396
14397         local facet
14398         for facet in client mds1 ost1; do
14399                 # Get the list of files that are missing the terminating newline
14400                 local plist=$(do_facet $facet
14401                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14402                 local ent
14403                 for ent in $plist; do
14404                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14405                                 awk -v FS='\v' -v RS='\v\v' \
14406                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14407                                         print FILENAME}'" 2>/dev/null)
14408                         [ -z $missing ] || {
14409                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14410                                 error "file does not end with newline: $facet-$ent"
14411                         }
14412                 done
14413         done
14414 }
14415 run_test 133h "Proc files should end with newlines"
14416
14417 test_134a() {
14418         remote_mds_nodsh && skip "remote MDS with nodsh"
14419         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14420                 skip "Need MDS version at least 2.7.54"
14421
14422         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14423         cancel_lru_locks mdc
14424
14425         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14426         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14427         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14428
14429         local nr=1000
14430         createmany -o $DIR/$tdir/f $nr ||
14431                 error "failed to create $nr files in $DIR/$tdir"
14432         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14433
14434         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14435         do_facet mds1 $LCTL set_param fail_loc=0x327
14436         do_facet mds1 $LCTL set_param fail_val=500
14437         touch $DIR/$tdir/m
14438
14439         echo "sleep 10 seconds ..."
14440         sleep 10
14441         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14442
14443         do_facet mds1 $LCTL set_param fail_loc=0
14444         do_facet mds1 $LCTL set_param fail_val=0
14445         [ $lck_cnt -lt $unused ] ||
14446                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14447
14448         rm $DIR/$tdir/m
14449         unlinkmany $DIR/$tdir/f $nr
14450 }
14451 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14452
14453 test_134b() {
14454         remote_mds_nodsh && skip "remote MDS with nodsh"
14455         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14456                 skip "Need MDS version at least 2.7.54"
14457
14458         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14459         cancel_lru_locks mdc
14460
14461         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14462                         ldlm.lock_reclaim_threshold_mb)
14463         # disable reclaim temporarily
14464         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14465
14466         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14467         do_facet mds1 $LCTL set_param fail_loc=0x328
14468         do_facet mds1 $LCTL set_param fail_val=500
14469
14470         $LCTL set_param debug=+trace
14471
14472         local nr=600
14473         createmany -o $DIR/$tdir/f $nr &
14474         local create_pid=$!
14475
14476         echo "Sleep $TIMEOUT seconds ..."
14477         sleep $TIMEOUT
14478         if ! ps -p $create_pid  > /dev/null 2>&1; then
14479                 do_facet mds1 $LCTL set_param fail_loc=0
14480                 do_facet mds1 $LCTL set_param fail_val=0
14481                 do_facet mds1 $LCTL set_param \
14482                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14483                 error "createmany finished incorrectly!"
14484         fi
14485         do_facet mds1 $LCTL set_param fail_loc=0
14486         do_facet mds1 $LCTL set_param fail_val=0
14487         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14488         wait $create_pid || return 1
14489
14490         unlinkmany $DIR/$tdir/f $nr
14491 }
14492 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14493
14494 test_135() {
14495         remote_mds_nodsh && skip "remote MDS with nodsh"
14496         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14497                 skip "Need MDS version at least 2.13.50"
14498         local fname
14499
14500         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14501
14502 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14503         #set only one record at plain llog
14504         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14505
14506         #fill already existed plain llog each 64767
14507         #wrapping whole catalog
14508         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14509
14510         createmany -o $DIR/$tdir/$tfile_ 64700
14511         for (( i = 0; i < 64700; i = i + 2 ))
14512         do
14513                 rm $DIR/$tdir/$tfile_$i &
14514                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14515                 local pid=$!
14516                 wait $pid
14517         done
14518
14519         #waiting osp synchronization
14520         wait_delete_completed
14521 }
14522 run_test 135 "Race catalog processing"
14523
14524 test_136() {
14525         remote_mds_nodsh && skip "remote MDS with nodsh"
14526         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14527                 skip "Need MDS version at least 2.13.50"
14528         local fname
14529
14530         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14531         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14532         #set only one record at plain llog
14533 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14534         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14535
14536         #fill already existed 2 plain llogs each 64767
14537         #wrapping whole catalog
14538         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14539         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14540         wait_delete_completed
14541
14542         createmany -o $DIR/$tdir/$tfile_ 10
14543         sleep 25
14544
14545         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14546         for (( i = 0; i < 10; i = i + 3 ))
14547         do
14548                 rm $DIR/$tdir/$tfile_$i &
14549                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14550                 local pid=$!
14551                 wait $pid
14552                 sleep 7
14553                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14554         done
14555
14556         #waiting osp synchronization
14557         wait_delete_completed
14558 }
14559 run_test 136 "Race catalog processing 2"
14560
14561 test_140() { #bug-17379
14562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14563
14564         test_mkdir $DIR/$tdir
14565         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14566         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14567
14568         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14569         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14570         local i=0
14571         while i=$((i + 1)); do
14572                 test_mkdir $i
14573                 cd $i || error "Changing to $i"
14574                 ln -s ../stat stat || error "Creating stat symlink"
14575                 # Read the symlink until ELOOP present,
14576                 # not LBUGing the system is considered success,
14577                 # we didn't overrun the stack.
14578                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14579                 if [ $ret -ne 0 ]; then
14580                         if [ $ret -eq 40 ]; then
14581                                 break  # -ELOOP
14582                         else
14583                                 error "Open stat symlink"
14584                                         return
14585                         fi
14586                 fi
14587         done
14588         i=$((i - 1))
14589         echo "The symlink depth = $i"
14590         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14591                 error "Invalid symlink depth"
14592
14593         # Test recursive symlink
14594         ln -s symlink_self symlink_self
14595         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14596         echo "open symlink_self returns $ret"
14597         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14598 }
14599 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14600
14601 test_150a() {
14602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14603
14604         local TF="$TMP/$tfile"
14605
14606         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14607         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14608         cp $TF $DIR/$tfile
14609         cancel_lru_locks $OSC
14610         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14611         remount_client $MOUNT
14612         df -P $MOUNT
14613         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14614
14615         $TRUNCATE $TF 6000
14616         $TRUNCATE $DIR/$tfile 6000
14617         cancel_lru_locks $OSC
14618         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14619
14620         echo "12345" >>$TF
14621         echo "12345" >>$DIR/$tfile
14622         cancel_lru_locks $OSC
14623         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14624
14625         echo "12345" >>$TF
14626         echo "12345" >>$DIR/$tfile
14627         cancel_lru_locks $OSC
14628         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14629 }
14630 run_test 150a "truncate/append tests"
14631
14632 test_150b() {
14633         check_set_fallocate_or_skip
14634
14635         touch $DIR/$tfile
14636         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14637         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14638 }
14639 run_test 150b "Verify fallocate (prealloc) functionality"
14640
14641 test_150bb() {
14642         check_set_fallocate_or_skip
14643
14644         touch $DIR/$tfile
14645         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14646         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14647         > $DIR/$tfile
14648         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14649         # precomputed md5sum for 20MB of zeroes
14650         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14651         local sum=($(md5sum $DIR/$tfile))
14652
14653         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14654
14655         check_set_fallocate 1
14656
14657         > $DIR/$tfile
14658         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14659         sum=($(md5sum $DIR/$tfile))
14660
14661         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14662 }
14663 run_test 150bb "Verify fallocate modes both zero space"
14664
14665 test_150c() {
14666         check_set_fallocate_or_skip
14667         local striping="-c2"
14668
14669         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14670         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14671         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14672         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14673         local want=$((OSTCOUNT * 1048576))
14674
14675         # Must allocate all requested space, not more than 5% extra
14676         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14677                 error "bytes $bytes is not $want"
14678
14679         rm -f $DIR/$tfile
14680
14681         echo "verify fallocate on PFL file"
14682
14683         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14684
14685         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14686                 error "Create $DIR/$tfile failed"
14687         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14688         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14689         want=$((512 * 1048576))
14690
14691         # Must allocate all requested space, not more than 5% extra
14692         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14693                 error "bytes $bytes is not $want"
14694 }
14695 run_test 150c "Verify fallocate Size and Blocks"
14696
14697 test_150d() {
14698         check_set_fallocate_or_skip
14699         local striping="-c2"
14700
14701         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14702
14703         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14704         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14705                 error "setstripe failed"
14706         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14707         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14708         local want=$((OSTCOUNT * 1048576))
14709
14710         # Must allocate all requested space, not more than 5% extra
14711         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14712                 error "bytes $bytes is not $want"
14713 }
14714 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14715
14716 test_150e() {
14717         check_set_fallocate_or_skip
14718
14719         echo "df before:"
14720         $LFS df
14721         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14722         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14723                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14724
14725         # Find OST with Minimum Size
14726         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14727                        sort -un | head -1)
14728
14729         # Get 100MB per OST of the available space to reduce run time
14730         # else 60% of the available space if we are running SLOW tests
14731         if [ $SLOW == "no" ]; then
14732                 local space=$((1024 * 100 * OSTCOUNT))
14733         else
14734                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14735         fi
14736
14737         fallocate -l${space}k $DIR/$tfile ||
14738                 error "fallocate ${space}k $DIR/$tfile failed"
14739         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14740
14741         # get size immediately after fallocate. This should be correctly
14742         # updated
14743         local size=$(stat -c '%s' $DIR/$tfile)
14744         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14745
14746         # Sleep for a while for statfs to get updated. And not pull from cache.
14747         sleep 2
14748
14749         echo "df after fallocate:"
14750         $LFS df
14751
14752         (( size / 1024 == space )) || error "size $size != requested $space"
14753         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14754                 error "used $used < space $space"
14755
14756         rm $DIR/$tfile || error "rm failed"
14757         sync
14758         wait_delete_completed
14759
14760         echo "df after unlink:"
14761         $LFS df
14762 }
14763 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14764
14765 test_150f() {
14766         local size
14767         local blocks
14768         local want_size_before=20480 # in bytes
14769         local want_blocks_before=40 # 512 sized blocks
14770         local want_blocks_after=24  # 512 sized blocks
14771         local length=$(((want_blocks_before - want_blocks_after) * 512))
14772
14773         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14774                 skip "need at least 2.14.0 for fallocate punch"
14775
14776         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14777                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14778         fi
14779
14780         check_set_fallocate_or_skip
14781         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14782
14783         [[ "x$DOM" == "xyes" ]] &&
14784                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14785
14786         echo "Verify fallocate punch: Range within the file range"
14787         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14788                 error "dd failed for bs 4096 and count 5"
14789
14790         # Call fallocate with punch range which is within the file range
14791         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14792                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14793         # client must see changes immediately after fallocate
14794         size=$(stat -c '%s' $DIR/$tfile)
14795         blocks=$(stat -c '%b' $DIR/$tfile)
14796
14797         # Verify punch worked.
14798         (( blocks == want_blocks_after )) ||
14799                 error "punch failed: blocks $blocks != $want_blocks_after"
14800
14801         (( size == want_size_before )) ||
14802                 error "punch failed: size $size != $want_size_before"
14803
14804         # Verify there is hole in file
14805         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14806         # precomputed md5sum
14807         local expect="4a9a834a2db02452929c0a348273b4aa"
14808
14809         cksum=($(md5sum $DIR/$tfile))
14810         [[ "${cksum[0]}" == "$expect" ]] ||
14811                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14812
14813         # Start second sub-case for fallocate punch.
14814         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14815         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14816                 error "dd failed for bs 4096 and count 5"
14817
14818         # Punch range less than block size will have no change in block count
14819         want_blocks_after=40  # 512 sized blocks
14820
14821         # Punch overlaps two blocks and less than blocksize
14822         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14823                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14824         size=$(stat -c '%s' $DIR/$tfile)
14825         blocks=$(stat -c '%b' $DIR/$tfile)
14826
14827         # Verify punch worked.
14828         (( blocks == want_blocks_after )) ||
14829                 error "punch failed: blocks $blocks != $want_blocks_after"
14830
14831         (( size == want_size_before )) ||
14832                 error "punch failed: size $size != $want_size_before"
14833
14834         # Verify if range is really zero'ed out. We expect Zeros.
14835         # precomputed md5sum
14836         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14837         cksum=($(md5sum $DIR/$tfile))
14838         [[ "${cksum[0]}" == "$expect" ]] ||
14839                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14840 }
14841 run_test 150f "Verify fallocate punch functionality"
14842
14843 test_150g() {
14844         local space
14845         local size
14846         local blocks
14847         local blocks_after
14848         local size_after
14849         local BS=4096 # Block size in bytes
14850
14851         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14852                 skip "need at least 2.14.0 for fallocate punch"
14853
14854         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14855                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14856         fi
14857
14858         check_set_fallocate_or_skip
14859         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14860
14861         if [[ "x$DOM" == "xyes" ]]; then
14862                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14863                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14864         else
14865                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14866                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14867         fi
14868
14869         # Get 100MB per OST of the available space to reduce run time
14870         # else 60% of the available space if we are running SLOW tests
14871         if [ $SLOW == "no" ]; then
14872                 space=$((1024 * 100 * OSTCOUNT))
14873         else
14874                 # Find OST with Minimum Size
14875                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14876                         sort -un | head -1)
14877                 echo "min size OST: $space"
14878                 space=$(((space * 60)/100 * OSTCOUNT))
14879         fi
14880         # space in 1k units, round to 4k blocks
14881         local blkcount=$((space * 1024 / $BS))
14882
14883         echo "Verify fallocate punch: Very large Range"
14884         fallocate -l${space}k $DIR/$tfile ||
14885                 error "fallocate ${space}k $DIR/$tfile failed"
14886         # write 1M at the end, start and in the middle
14887         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14888                 error "dd failed: bs $BS count 256"
14889         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14890                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14891         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14892                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14893
14894         # Gather stats.
14895         size=$(stat -c '%s' $DIR/$tfile)
14896
14897         # gather punch length.
14898         local punch_size=$((size - (BS * 2)))
14899
14900         echo "punch_size = $punch_size"
14901         echo "size - punch_size: $((size - punch_size))"
14902         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14903
14904         # Call fallocate to punch all except 2 blocks. We leave the
14905         # first and the last block
14906         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14907         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
14908                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
14909
14910         size_after=$(stat -c '%s' $DIR/$tfile)
14911         blocks_after=$(stat -c '%b' $DIR/$tfile)
14912
14913         # Verify punch worked.
14914         # Size should be kept
14915         (( size == size_after )) ||
14916                 error "punch failed: size $size != $size_after"
14917
14918         # two 4k data blocks to remain plus possible 1 extra extent block
14919         (( blocks_after <= ((BS / 512) * 3) )) ||
14920                 error "too many blocks remains: $blocks_after"
14921
14922         # Verify that file has hole between the first and the last blocks
14923         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14924         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14925
14926         echo "Hole at [$hole_start, $hole_end)"
14927         (( hole_start == BS )) ||
14928                 error "no hole at offset $BS after punch"
14929
14930         (( hole_end == BS + punch_size )) ||
14931                 error "data at offset $hole_end < $((BS + punch_size))"
14932 }
14933 run_test 150g "Verify fallocate punch on large range"
14934
14935 #LU-2902 roc_hit was not able to read all values from lproc
14936 function roc_hit_init() {
14937         local list=$(comma_list $(osts_nodes))
14938         local dir=$DIR/$tdir-check
14939         local file=$dir/$tfile
14940         local BEFORE
14941         local AFTER
14942         local idx
14943
14944         test_mkdir $dir
14945         #use setstripe to do a write to every ost
14946         for i in $(seq 0 $((OSTCOUNT-1))); do
14947                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14948                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14949                 idx=$(printf %04x $i)
14950                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14951                         awk '$1 == "cache_access" {sum += $7}
14952                                 END { printf("%0.0f", sum) }')
14953
14954                 cancel_lru_locks osc
14955                 cat $file >/dev/null
14956
14957                 AFTER=$(get_osd_param $list *OST*$idx stats |
14958                         awk '$1 == "cache_access" {sum += $7}
14959                                 END { printf("%0.0f", sum) }')
14960
14961                 echo BEFORE:$BEFORE AFTER:$AFTER
14962                 if ! let "AFTER - BEFORE == 4"; then
14963                         rm -rf $dir
14964                         error "roc_hit is not safe to use"
14965                 fi
14966                 rm $file
14967         done
14968
14969         rm -rf $dir
14970 }
14971
14972 function roc_hit() {
14973         local list=$(comma_list $(osts_nodes))
14974         echo $(get_osd_param $list '' stats |
14975                 awk '$1 == "cache_hit" {sum += $7}
14976                         END { printf("%0.0f", sum) }')
14977 }
14978
14979 function set_cache() {
14980         local on=1
14981
14982         if [ "$2" == "off" ]; then
14983                 on=0;
14984         fi
14985         local list=$(comma_list $(osts_nodes))
14986         set_osd_param $list '' $1_cache_enable $on
14987
14988         cancel_lru_locks osc
14989 }
14990
14991 test_151() {
14992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14993         remote_ost_nodsh && skip "remote OST with nodsh"
14994
14995         local CPAGES=3
14996         local list=$(comma_list $(osts_nodes))
14997
14998         # check whether obdfilter is cache capable at all
14999         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15000                 skip "not cache-capable obdfilter"
15001         fi
15002
15003         # check cache is enabled on all obdfilters
15004         if get_osd_param $list '' read_cache_enable | grep 0; then
15005                 skip "oss cache is disabled"
15006         fi
15007
15008         set_osd_param $list '' writethrough_cache_enable 1
15009
15010         # check write cache is enabled on all obdfilters
15011         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15012                 skip "oss write cache is NOT enabled"
15013         fi
15014
15015         roc_hit_init
15016
15017         #define OBD_FAIL_OBD_NO_LRU  0x609
15018         do_nodes $list $LCTL set_param fail_loc=0x609
15019
15020         # pages should be in the case right after write
15021         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15022                 error "dd failed"
15023
15024         local BEFORE=$(roc_hit)
15025         cancel_lru_locks osc
15026         cat $DIR/$tfile >/dev/null
15027         local AFTER=$(roc_hit)
15028
15029         do_nodes $list $LCTL set_param fail_loc=0
15030
15031         if ! let "AFTER - BEFORE == CPAGES"; then
15032                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15033         fi
15034
15035         cancel_lru_locks osc
15036         # invalidates OST cache
15037         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15038         set_osd_param $list '' read_cache_enable 0
15039         cat $DIR/$tfile >/dev/null
15040
15041         # now data shouldn't be found in the cache
15042         BEFORE=$(roc_hit)
15043         cancel_lru_locks osc
15044         cat $DIR/$tfile >/dev/null
15045         AFTER=$(roc_hit)
15046         if let "AFTER - BEFORE != 0"; then
15047                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15048         fi
15049
15050         set_osd_param $list '' read_cache_enable 1
15051         rm -f $DIR/$tfile
15052 }
15053 run_test 151 "test cache on oss and controls ==============================="
15054
15055 test_152() {
15056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15057
15058         local TF="$TMP/$tfile"
15059
15060         # simulate ENOMEM during write
15061 #define OBD_FAIL_OST_NOMEM      0x226
15062         lctl set_param fail_loc=0x80000226
15063         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15064         cp $TF $DIR/$tfile
15065         sync || error "sync failed"
15066         lctl set_param fail_loc=0
15067
15068         # discard client's cache
15069         cancel_lru_locks osc
15070
15071         # simulate ENOMEM during read
15072         lctl set_param fail_loc=0x80000226
15073         cmp $TF $DIR/$tfile || error "cmp failed"
15074         lctl set_param fail_loc=0
15075
15076         rm -f $TF
15077 }
15078 run_test 152 "test read/write with enomem ============================"
15079
15080 test_153() {
15081         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15082 }
15083 run_test 153 "test if fdatasync does not crash ======================="
15084
15085 dot_lustre_fid_permission_check() {
15086         local fid=$1
15087         local ffid=$MOUNT/.lustre/fid/$fid
15088         local test_dir=$2
15089
15090         echo "stat fid $fid"
15091         stat $ffid > /dev/null || error "stat $ffid failed."
15092         echo "touch fid $fid"
15093         touch $ffid || error "touch $ffid failed."
15094         echo "write to fid $fid"
15095         cat /etc/hosts > $ffid || error "write $ffid failed."
15096         echo "read fid $fid"
15097         diff /etc/hosts $ffid || error "read $ffid failed."
15098         echo "append write to fid $fid"
15099         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15100         echo "rename fid $fid"
15101         mv $ffid $test_dir/$tfile.1 &&
15102                 error "rename $ffid to $tfile.1 should fail."
15103         touch $test_dir/$tfile.1
15104         mv $test_dir/$tfile.1 $ffid &&
15105                 error "rename $tfile.1 to $ffid should fail."
15106         rm -f $test_dir/$tfile.1
15107         echo "truncate fid $fid"
15108         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15109         echo "link fid $fid"
15110         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15111         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15112                 echo "setfacl fid $fid"
15113                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15114                 echo "getfacl fid $fid"
15115                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15116         fi
15117         echo "unlink fid $fid"
15118         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15119         echo "mknod fid $fid"
15120         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15121
15122         fid=[0xf00000400:0x1:0x0]
15123         ffid=$MOUNT/.lustre/fid/$fid
15124
15125         echo "stat non-exist fid $fid"
15126         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15127         echo "write to non-exist fid $fid"
15128         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15129         echo "link new fid $fid"
15130         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15131
15132         mkdir -p $test_dir/$tdir
15133         touch $test_dir/$tdir/$tfile
15134         fid=$($LFS path2fid $test_dir/$tdir)
15135         rc=$?
15136         [ $rc -ne 0 ] &&
15137                 error "error: could not get fid for $test_dir/$dir/$tfile."
15138
15139         ffid=$MOUNT/.lustre/fid/$fid
15140
15141         echo "ls $fid"
15142         ls $ffid > /dev/null || error "ls $ffid failed."
15143         echo "touch $fid/$tfile.1"
15144         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15145
15146         echo "touch $MOUNT/.lustre/fid/$tfile"
15147         touch $MOUNT/.lustre/fid/$tfile && \
15148                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15149
15150         echo "setxattr to $MOUNT/.lustre/fid"
15151         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15152
15153         echo "listxattr for $MOUNT/.lustre/fid"
15154         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15155
15156         echo "delxattr from $MOUNT/.lustre/fid"
15157         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15158
15159         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15160         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15161                 error "touch invalid fid should fail."
15162
15163         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15164         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15165                 error "touch non-normal fid should fail."
15166
15167         echo "rename $tdir to $MOUNT/.lustre/fid"
15168         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15169                 error "rename to $MOUNT/.lustre/fid should fail."
15170
15171         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15172         then            # LU-3547
15173                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15174                 local new_obf_mode=777
15175
15176                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15177                 chmod $new_obf_mode $DIR/.lustre/fid ||
15178                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15179
15180                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15181                 [ $obf_mode -eq $new_obf_mode ] ||
15182                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15183
15184                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15185                 chmod $old_obf_mode $DIR/.lustre/fid ||
15186                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15187         fi
15188
15189         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15190         fid=$($LFS path2fid $test_dir/$tfile-2)
15191
15192         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15193         then # LU-5424
15194                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15195                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15196                         error "create lov data thru .lustre failed"
15197         fi
15198         echo "cp /etc/passwd $test_dir/$tfile-2"
15199         cp /etc/passwd $test_dir/$tfile-2 ||
15200                 error "copy to $test_dir/$tfile-2 failed."
15201         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15202         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15203                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15204
15205         rm -rf $test_dir/tfile.lnk
15206         rm -rf $test_dir/$tfile-2
15207 }
15208
15209 test_154A() {
15210         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15211                 skip "Need MDS version at least 2.4.1"
15212
15213         local tf=$DIR/$tfile
15214         touch $tf
15215
15216         local fid=$($LFS path2fid $tf)
15217         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15218
15219         # check that we get the same pathname back
15220         local rootpath
15221         local found
15222         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15223                 echo "$rootpath $fid"
15224                 found=$($LFS fid2path $rootpath "$fid")
15225                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15226                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15227         done
15228
15229         # check wrong root path format
15230         rootpath=$MOUNT"_wrong"
15231         found=$($LFS fid2path $rootpath "$fid")
15232         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15233 }
15234 run_test 154A "lfs path2fid and fid2path basic checks"
15235
15236 test_154B() {
15237         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15238                 skip "Need MDS version at least 2.4.1"
15239
15240         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15241         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15242         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15243         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15244
15245         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15246         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15247
15248         # check that we get the same pathname
15249         echo "PFID: $PFID, name: $name"
15250         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15251         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15252         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15253                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15254
15255         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15256 }
15257 run_test 154B "verify the ll_decode_linkea tool"
15258
15259 test_154a() {
15260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15261         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15262         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15263                 skip "Need MDS version at least 2.2.51"
15264         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15265
15266         cp /etc/hosts $DIR/$tfile
15267
15268         fid=$($LFS path2fid $DIR/$tfile)
15269         rc=$?
15270         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15271
15272         dot_lustre_fid_permission_check "$fid" $DIR ||
15273                 error "dot lustre permission check $fid failed"
15274
15275         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15276
15277         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15278
15279         touch $MOUNT/.lustre/file &&
15280                 error "creation is not allowed under .lustre"
15281
15282         mkdir $MOUNT/.lustre/dir &&
15283                 error "mkdir is not allowed under .lustre"
15284
15285         rm -rf $DIR/$tfile
15286 }
15287 run_test 154a "Open-by-FID"
15288
15289 test_154b() {
15290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15291         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15292         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15293         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15294                 skip "Need MDS version at least 2.2.51"
15295
15296         local remote_dir=$DIR/$tdir/remote_dir
15297         local MDTIDX=1
15298         local rc=0
15299
15300         mkdir -p $DIR/$tdir
15301         $LFS mkdir -i $MDTIDX $remote_dir ||
15302                 error "create remote directory failed"
15303
15304         cp /etc/hosts $remote_dir/$tfile
15305
15306         fid=$($LFS path2fid $remote_dir/$tfile)
15307         rc=$?
15308         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15309
15310         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15311                 error "dot lustre permission check $fid failed"
15312         rm -rf $DIR/$tdir
15313 }
15314 run_test 154b "Open-by-FID for remote directory"
15315
15316 test_154c() {
15317         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15318                 skip "Need MDS version at least 2.4.1"
15319
15320         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15321         local FID1=$($LFS path2fid $DIR/$tfile.1)
15322         local FID2=$($LFS path2fid $DIR/$tfile.2)
15323         local FID3=$($LFS path2fid $DIR/$tfile.3)
15324
15325         local N=1
15326         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15327                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15328                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15329                 local want=FID$N
15330                 [ "$FID" = "${!want}" ] ||
15331                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15332                 N=$((N + 1))
15333         done
15334
15335         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15336         do
15337                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15338                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15339                 N=$((N + 1))
15340         done
15341 }
15342 run_test 154c "lfs path2fid and fid2path multiple arguments"
15343
15344 test_154d() {
15345         remote_mds_nodsh && skip "remote MDS with nodsh"
15346         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15347                 skip "Need MDS version at least 2.5.53"
15348
15349         if remote_mds; then
15350                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15351         else
15352                 nid="0@lo"
15353         fi
15354         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15355         local fd
15356         local cmd
15357
15358         rm -f $DIR/$tfile
15359         touch $DIR/$tfile
15360
15361         local fid=$($LFS path2fid $DIR/$tfile)
15362         # Open the file
15363         fd=$(free_fd)
15364         cmd="exec $fd<$DIR/$tfile"
15365         eval $cmd
15366         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15367         echo "$fid_list" | grep "$fid"
15368         rc=$?
15369
15370         cmd="exec $fd>/dev/null"
15371         eval $cmd
15372         if [ $rc -ne 0 ]; then
15373                 error "FID $fid not found in open files list $fid_list"
15374         fi
15375 }
15376 run_test 154d "Verify open file fid"
15377
15378 test_154e()
15379 {
15380         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15381                 skip "Need MDS version at least 2.6.50"
15382
15383         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15384                 error ".lustre returned by readdir"
15385         fi
15386 }
15387 run_test 154e ".lustre is not returned by readdir"
15388
15389 test_154f() {
15390         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15391
15392         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15393         mkdir_on_mdt0 $DIR/$tdir
15394         # test dirs inherit from its stripe
15395         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15396         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15397         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15398         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15399         touch $DIR/f
15400
15401         # get fid of parents
15402         local FID0=$($LFS path2fid $DIR/$tdir)
15403         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15404         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15405         local FID3=$($LFS path2fid $DIR)
15406
15407         # check that path2fid --parents returns expected <parent_fid>/name
15408         # 1) test for a directory (single parent)
15409         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15410         [ "$parent" == "$FID0/foo1" ] ||
15411                 error "expected parent: $FID0/foo1, got: $parent"
15412
15413         # 2) test for a file with nlink > 1 (multiple parents)
15414         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15415         echo "$parent" | grep -F "$FID1/$tfile" ||
15416                 error "$FID1/$tfile not returned in parent list"
15417         echo "$parent" | grep -F "$FID2/link" ||
15418                 error "$FID2/link not returned in parent list"
15419
15420         # 3) get parent by fid
15421         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15422         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15423         echo "$parent" | grep -F "$FID1/$tfile" ||
15424                 error "$FID1/$tfile not returned in parent list (by fid)"
15425         echo "$parent" | grep -F "$FID2/link" ||
15426                 error "$FID2/link not returned in parent list (by fid)"
15427
15428         # 4) test for entry in root directory
15429         parent=$($LFS path2fid --parents $DIR/f)
15430         echo "$parent" | grep -F "$FID3/f" ||
15431                 error "$FID3/f not returned in parent list"
15432
15433         # 5) test it on root directory
15434         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15435                 error "$MOUNT should not have parents"
15436
15437         # enable xattr caching and check that linkea is correctly updated
15438         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15439         save_lustre_params client "llite.*.xattr_cache" > $save
15440         lctl set_param llite.*.xattr_cache 1
15441
15442         # 6.1) linkea update on rename
15443         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15444
15445         # get parents by fid
15446         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15447         # foo1 should no longer be returned in parent list
15448         echo "$parent" | grep -F "$FID1" &&
15449                 error "$FID1 should no longer be in parent list"
15450         # the new path should appear
15451         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15452                 error "$FID2/$tfile.moved is not in parent list"
15453
15454         # 6.2) linkea update on unlink
15455         rm -f $DIR/$tdir/foo2/link
15456         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15457         # foo2/link should no longer be returned in parent list
15458         echo "$parent" | grep -F "$FID2/link" &&
15459                 error "$FID2/link should no longer be in parent list"
15460         true
15461
15462         rm -f $DIR/f
15463         restore_lustre_params < $save
15464         rm -f $save
15465 }
15466 run_test 154f "get parent fids by reading link ea"
15467
15468 test_154g()
15469 {
15470         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15471         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15472            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15473                 skip "Need MDS version at least 2.6.92"
15474
15475         mkdir_on_mdt0 $DIR/$tdir
15476         llapi_fid_test -d $DIR/$tdir
15477 }
15478 run_test 154g "various llapi FID tests"
15479
15480 test_155_small_load() {
15481     local temp=$TMP/$tfile
15482     local file=$DIR/$tfile
15483
15484     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15485         error "dd of=$temp bs=6096 count=1 failed"
15486     cp $temp $file
15487     cancel_lru_locks $OSC
15488     cmp $temp $file || error "$temp $file differ"
15489
15490     $TRUNCATE $temp 6000
15491     $TRUNCATE $file 6000
15492     cmp $temp $file || error "$temp $file differ (truncate1)"
15493
15494     echo "12345" >>$temp
15495     echo "12345" >>$file
15496     cmp $temp $file || error "$temp $file differ (append1)"
15497
15498     echo "12345" >>$temp
15499     echo "12345" >>$file
15500     cmp $temp $file || error "$temp $file differ (append2)"
15501
15502     rm -f $temp $file
15503     true
15504 }
15505
15506 test_155_big_load() {
15507         remote_ost_nodsh && skip "remote OST with nodsh"
15508
15509         local temp=$TMP/$tfile
15510         local file=$DIR/$tfile
15511
15512         free_min_max
15513         local cache_size=$(do_facet ost$((MAXI+1)) \
15514                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15515         local large_file_size=$((cache_size * 2))
15516
15517         echo "OSS cache size: $cache_size KB"
15518         echo "Large file size: $large_file_size KB"
15519
15520         [ $MAXV -le $large_file_size ] &&
15521                 skip_env "max available OST size needs > $large_file_size KB"
15522
15523         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15524
15525         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15526                 error "dd of=$temp bs=$large_file_size count=1k failed"
15527         cp $temp $file
15528         ls -lh $temp $file
15529         cancel_lru_locks osc
15530         cmp $temp $file || error "$temp $file differ"
15531
15532         rm -f $temp $file
15533         true
15534 }
15535
15536 save_writethrough() {
15537         local facets=$(get_facets OST)
15538
15539         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15540 }
15541
15542 test_155a() {
15543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15544
15545         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15546
15547         save_writethrough $p
15548
15549         set_cache read on
15550         set_cache writethrough on
15551         test_155_small_load
15552         restore_lustre_params < $p
15553         rm -f $p
15554 }
15555 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15556
15557 test_155b() {
15558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15559
15560         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15561
15562         save_writethrough $p
15563
15564         set_cache read on
15565         set_cache writethrough off
15566         test_155_small_load
15567         restore_lustre_params < $p
15568         rm -f $p
15569 }
15570 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15571
15572 test_155c() {
15573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15574
15575         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15576
15577         save_writethrough $p
15578
15579         set_cache read off
15580         set_cache writethrough on
15581         test_155_small_load
15582         restore_lustre_params < $p
15583         rm -f $p
15584 }
15585 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15586
15587 test_155d() {
15588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15589
15590         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15591
15592         save_writethrough $p
15593
15594         set_cache read off
15595         set_cache writethrough off
15596         test_155_small_load
15597         restore_lustre_params < $p
15598         rm -f $p
15599 }
15600 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15601
15602 test_155e() {
15603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15604
15605         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15606
15607         save_writethrough $p
15608
15609         set_cache read on
15610         set_cache writethrough on
15611         test_155_big_load
15612         restore_lustre_params < $p
15613         rm -f $p
15614 }
15615 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15616
15617 test_155f() {
15618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15619
15620         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15621
15622         save_writethrough $p
15623
15624         set_cache read on
15625         set_cache writethrough off
15626         test_155_big_load
15627         restore_lustre_params < $p
15628         rm -f $p
15629 }
15630 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15631
15632 test_155g() {
15633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15634
15635         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15636
15637         save_writethrough $p
15638
15639         set_cache read off
15640         set_cache writethrough on
15641         test_155_big_load
15642         restore_lustre_params < $p
15643         rm -f $p
15644 }
15645 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15646
15647 test_155h() {
15648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15649
15650         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15651
15652         save_writethrough $p
15653
15654         set_cache read off
15655         set_cache writethrough off
15656         test_155_big_load
15657         restore_lustre_params < $p
15658         rm -f $p
15659 }
15660 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15661
15662 test_156() {
15663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15664         remote_ost_nodsh && skip "remote OST with nodsh"
15665         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15666                 skip "stats not implemented on old servers"
15667         [ "$ost1_FSTYPE" = "zfs" ] &&
15668                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15669
15670         local CPAGES=3
15671         local BEFORE
15672         local AFTER
15673         local file="$DIR/$tfile"
15674         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15675
15676         save_writethrough $p
15677         roc_hit_init
15678
15679         log "Turn on read and write cache"
15680         set_cache read on
15681         set_cache writethrough on
15682
15683         log "Write data and read it back."
15684         log "Read should be satisfied from the cache."
15685         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15686         BEFORE=$(roc_hit)
15687         cancel_lru_locks osc
15688         cat $file >/dev/null
15689         AFTER=$(roc_hit)
15690         if ! let "AFTER - BEFORE == CPAGES"; then
15691                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15692         else
15693                 log "cache hits: before: $BEFORE, after: $AFTER"
15694         fi
15695
15696         log "Read again; it should be satisfied from the cache."
15697         BEFORE=$AFTER
15698         cancel_lru_locks osc
15699         cat $file >/dev/null
15700         AFTER=$(roc_hit)
15701         if ! let "AFTER - BEFORE == CPAGES"; then
15702                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15703         else
15704                 log "cache hits:: before: $BEFORE, after: $AFTER"
15705         fi
15706
15707         log "Turn off the read cache and turn on the write cache"
15708         set_cache read off
15709         set_cache writethrough on
15710
15711         log "Read again; it should be satisfied from the cache."
15712         BEFORE=$(roc_hit)
15713         cancel_lru_locks osc
15714         cat $file >/dev/null
15715         AFTER=$(roc_hit)
15716         if ! let "AFTER - BEFORE == CPAGES"; then
15717                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15718         else
15719                 log "cache hits:: before: $BEFORE, after: $AFTER"
15720         fi
15721
15722         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15723                 # > 2.12.56 uses pagecache if cached
15724                 log "Read again; it should not be satisfied from the cache."
15725                 BEFORE=$AFTER
15726                 cancel_lru_locks osc
15727                 cat $file >/dev/null
15728                 AFTER=$(roc_hit)
15729                 if ! let "AFTER - BEFORE == 0"; then
15730                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15731                 else
15732                         log "cache hits:: before: $BEFORE, after: $AFTER"
15733                 fi
15734         fi
15735
15736         log "Write data and read it back."
15737         log "Read should be satisfied from the cache."
15738         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15739         BEFORE=$(roc_hit)
15740         cancel_lru_locks osc
15741         cat $file >/dev/null
15742         AFTER=$(roc_hit)
15743         if ! let "AFTER - BEFORE == CPAGES"; then
15744                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15745         else
15746                 log "cache hits:: before: $BEFORE, after: $AFTER"
15747         fi
15748
15749         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15750                 # > 2.12.56 uses pagecache if cached
15751                 log "Read again; it should not be satisfied from the cache."
15752                 BEFORE=$AFTER
15753                 cancel_lru_locks osc
15754                 cat $file >/dev/null
15755                 AFTER=$(roc_hit)
15756                 if ! let "AFTER - BEFORE == 0"; then
15757                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15758                 else
15759                         log "cache hits:: before: $BEFORE, after: $AFTER"
15760                 fi
15761         fi
15762
15763         log "Turn off read and write cache"
15764         set_cache read off
15765         set_cache writethrough off
15766
15767         log "Write data and read it back"
15768         log "It should not be satisfied from the cache."
15769         rm -f $file
15770         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15771         cancel_lru_locks osc
15772         BEFORE=$(roc_hit)
15773         cat $file >/dev/null
15774         AFTER=$(roc_hit)
15775         if ! let "AFTER - BEFORE == 0"; then
15776                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15777         else
15778                 log "cache hits:: before: $BEFORE, after: $AFTER"
15779         fi
15780
15781         log "Turn on the read cache and turn off the write cache"
15782         set_cache read on
15783         set_cache writethrough off
15784
15785         log "Write data and read it back"
15786         log "It should not be satisfied from the cache."
15787         rm -f $file
15788         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15789         BEFORE=$(roc_hit)
15790         cancel_lru_locks osc
15791         cat $file >/dev/null
15792         AFTER=$(roc_hit)
15793         if ! let "AFTER - BEFORE == 0"; then
15794                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15795         else
15796                 log "cache hits:: before: $BEFORE, after: $AFTER"
15797         fi
15798
15799         log "Read again; it should be satisfied from the cache."
15800         BEFORE=$(roc_hit)
15801         cancel_lru_locks osc
15802         cat $file >/dev/null
15803         AFTER=$(roc_hit)
15804         if ! let "AFTER - BEFORE == CPAGES"; then
15805                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15806         else
15807                 log "cache hits:: before: $BEFORE, after: $AFTER"
15808         fi
15809
15810         restore_lustre_params < $p
15811         rm -f $p $file
15812 }
15813 run_test 156 "Verification of tunables"
15814
15815 test_160a() {
15816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15817         remote_mds_nodsh && skip "remote MDS with nodsh"
15818         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15819                 skip "Need MDS version at least 2.2.0"
15820
15821         changelog_register || error "changelog_register failed"
15822         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15823         changelog_users $SINGLEMDS | grep -q $cl_user ||
15824                 error "User $cl_user not found in changelog_users"
15825
15826         mkdir_on_mdt0 $DIR/$tdir
15827
15828         # change something
15829         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15830         changelog_clear 0 || error "changelog_clear failed"
15831         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15832         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15833         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15834         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15835         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15836         rm $DIR/$tdir/pics/desktop.jpg
15837
15838         echo "verifying changelog mask"
15839         changelog_chmask "-MKDIR"
15840         changelog_chmask "-CLOSE"
15841
15842         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15843         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15844
15845         changelog_chmask "+MKDIR"
15846         changelog_chmask "+CLOSE"
15847
15848         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15849         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15850
15851         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15852         CLOSES=$(changelog_dump | grep -c "CLOSE")
15853         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15854         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15855
15856         # verify contents
15857         echo "verifying target fid"
15858         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15859         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15860         [ "$fidc" == "$fidf" ] ||
15861                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15862         echo "verifying parent fid"
15863         # The FID returned from the Changelog may be the directory shard on
15864         # a different MDT, and not the FID returned by path2fid on the parent.
15865         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15866         # since this is what will matter when recreating this file in the tree.
15867         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15868         local pathp=$($LFS fid2path $MOUNT "$fidp")
15869         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15870                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15871
15872         echo "getting records for $cl_user"
15873         changelog_users $SINGLEMDS
15874         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15875         local nclr=3
15876         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15877                 error "changelog_clear failed"
15878         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15879         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15880         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15881                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15882
15883         local min0_rec=$(changelog_users $SINGLEMDS |
15884                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15885         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15886                           awk '{ print $1; exit; }')
15887
15888         changelog_dump | tail -n 5
15889         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15890         [ $first_rec == $((min0_rec + 1)) ] ||
15891                 error "first index should be $min0_rec + 1 not $first_rec"
15892
15893         # LU-3446 changelog index reset on MDT restart
15894         local cur_rec1=$(changelog_users $SINGLEMDS |
15895                          awk '/^current.index:/ { print $NF }')
15896         changelog_clear 0 ||
15897                 error "clear all changelog records for $cl_user failed"
15898         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15899         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15900                 error "Fail to start $SINGLEMDS"
15901         local cur_rec2=$(changelog_users $SINGLEMDS |
15902                          awk '/^current.index:/ { print $NF }')
15903         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15904         [ $cur_rec1 == $cur_rec2 ] ||
15905                 error "current index should be $cur_rec1 not $cur_rec2"
15906
15907         echo "verifying users from this test are deregistered"
15908         changelog_deregister || error "changelog_deregister failed"
15909         changelog_users $SINGLEMDS | grep -q $cl_user &&
15910                 error "User '$cl_user' still in changelog_users"
15911
15912         # lctl get_param -n mdd.*.changelog_users
15913         # current_index: 144
15914         # ID    index (idle seconds)
15915         # cl3   144   (2) mask=<list>
15916         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15917                 # this is the normal case where all users were deregistered
15918                 # make sure no new records are added when no users are present
15919                 local last_rec1=$(changelog_users $SINGLEMDS |
15920                                   awk '/^current.index:/ { print $NF }')
15921                 touch $DIR/$tdir/chloe
15922                 local last_rec2=$(changelog_users $SINGLEMDS |
15923                                   awk '/^current.index:/ { print $NF }')
15924                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15925                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15926         else
15927                 # any changelog users must be leftovers from a previous test
15928                 changelog_users $SINGLEMDS
15929                 echo "other changelog users; can't verify off"
15930         fi
15931 }
15932 run_test 160a "changelog sanity"
15933
15934 test_160b() { # LU-3587
15935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15936         remote_mds_nodsh && skip "remote MDS with nodsh"
15937         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15938                 skip "Need MDS version at least 2.2.0"
15939
15940         changelog_register || error "changelog_register failed"
15941         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15942         changelog_users $SINGLEMDS | grep -q $cl_user ||
15943                 error "User '$cl_user' not found in changelog_users"
15944
15945         local longname1=$(str_repeat a 255)
15946         local longname2=$(str_repeat b 255)
15947
15948         cd $DIR
15949         echo "creating very long named file"
15950         touch $longname1 || error "create of '$longname1' failed"
15951         echo "renaming very long named file"
15952         mv $longname1 $longname2
15953
15954         changelog_dump | grep RENME | tail -n 5
15955         rm -f $longname2
15956 }
15957 run_test 160b "Verify that very long rename doesn't crash in changelog"
15958
15959 test_160c() {
15960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15961         remote_mds_nodsh && skip "remote MDS with nodsh"
15962
15963         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15964                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15965                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15966                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15967
15968         local rc=0
15969
15970         # Registration step
15971         changelog_register || error "changelog_register failed"
15972
15973         rm -rf $DIR/$tdir
15974         mkdir -p $DIR/$tdir
15975         $MCREATE $DIR/$tdir/foo_160c
15976         changelog_chmask "-TRUNC"
15977         $TRUNCATE $DIR/$tdir/foo_160c 200
15978         changelog_chmask "+TRUNC"
15979         $TRUNCATE $DIR/$tdir/foo_160c 199
15980         changelog_dump | tail -n 5
15981         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15982         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15983 }
15984 run_test 160c "verify that changelog log catch the truncate event"
15985
15986 test_160d() {
15987         remote_mds_nodsh && skip "remote MDS with nodsh"
15988         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15990         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15991                 skip "Need MDS version at least 2.7.60"
15992
15993         # Registration step
15994         changelog_register || error "changelog_register failed"
15995
15996         mkdir -p $DIR/$tdir/migrate_dir
15997         changelog_clear 0 || error "changelog_clear failed"
15998
15999         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16000         changelog_dump | tail -n 5
16001         local migrates=$(changelog_dump | grep -c "MIGRT")
16002         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16003 }
16004 run_test 160d "verify that changelog log catch the migrate event"
16005
16006 test_160e() {
16007         remote_mds_nodsh && skip "remote MDS with nodsh"
16008
16009         # Create a user
16010         changelog_register || error "changelog_register failed"
16011
16012         local MDT0=$(facet_svc $SINGLEMDS)
16013         local rc
16014
16015         # No user (expect fail)
16016         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16017         rc=$?
16018         if [ $rc -eq 0 ]; then
16019                 error "Should fail without user"
16020         elif [ $rc -ne 4 ]; then
16021                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16022         fi
16023
16024         # Delete a future user (expect fail)
16025         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16026         rc=$?
16027         if [ $rc -eq 0 ]; then
16028                 error "Deleted non-existant user cl77"
16029         elif [ $rc -ne 2 ]; then
16030                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16031         fi
16032
16033         # Clear to a bad index (1 billion should be safe)
16034         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16035         rc=$?
16036
16037         if [ $rc -eq 0 ]; then
16038                 error "Successfully cleared to invalid CL index"
16039         elif [ $rc -ne 22 ]; then
16040                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16041         fi
16042 }
16043 run_test 160e "changelog negative testing (should return errors)"
16044
16045 test_160f() {
16046         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16047         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16048                 skip "Need MDS version at least 2.10.56"
16049
16050         local mdts=$(comma_list $(mdts_nodes))
16051
16052         # Create a user
16053         changelog_register || error "first changelog_register failed"
16054         changelog_register || error "second changelog_register failed"
16055         local cl_users
16056         declare -A cl_user1
16057         declare -A cl_user2
16058         local user_rec1
16059         local user_rec2
16060         local i
16061
16062         # generate some changelog records to accumulate on each MDT
16063         # use all_char because created files should be evenly distributed
16064         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16065                 error "test_mkdir $tdir failed"
16066         log "$(date +%s): creating first files"
16067         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16068                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16069                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16070         done
16071
16072         # check changelogs have been generated
16073         local start=$SECONDS
16074         local idle_time=$((MDSCOUNT * 5 + 5))
16075         local nbcl=$(changelog_dump | wc -l)
16076         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16077
16078         for param in "changelog_max_idle_time=$idle_time" \
16079                      "changelog_gc=1" \
16080                      "changelog_min_gc_interval=2" \
16081                      "changelog_min_free_cat_entries=3"; do
16082                 local MDT0=$(facet_svc $SINGLEMDS)
16083                 local var="${param%=*}"
16084                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16085
16086                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16087                 do_nodes $mdts $LCTL set_param mdd.*.$param
16088         done
16089
16090         # force cl_user2 to be idle (1st part), but also cancel the
16091         # cl_user1 records so that it is not evicted later in the test.
16092         local sleep1=$((idle_time / 2))
16093         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16094         sleep $sleep1
16095
16096         # simulate changelog catalog almost full
16097         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16098         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16099
16100         for i in $(seq $MDSCOUNT); do
16101                 cl_users=(${CL_USERS[mds$i]})
16102                 cl_user1[mds$i]="${cl_users[0]}"
16103                 cl_user2[mds$i]="${cl_users[1]}"
16104
16105                 [ -n "${cl_user1[mds$i]}" ] ||
16106                         error "mds$i: no user registered"
16107                 [ -n "${cl_user2[mds$i]}" ] ||
16108                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16109
16110                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16111                 [ -n "$user_rec1" ] ||
16112                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16113                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16114                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16115                 [ -n "$user_rec2" ] ||
16116                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16117                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16118                      "$user_rec1 + 2 == $user_rec2"
16119                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16120                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16121                               "$user_rec1 + 2, but is $user_rec2"
16122                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16123                 [ -n "$user_rec2" ] ||
16124                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16125                 [ $user_rec1 == $user_rec2 ] ||
16126                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16127                               "$user_rec1, but is $user_rec2"
16128         done
16129
16130         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16131         local sleep2=$((idle_time - (SECONDS - start) + 1))
16132         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16133         sleep $sleep2
16134
16135         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16136         # cl_user1 should be OK because it recently processed records.
16137         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16138         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16139                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16140                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16141         done
16142
16143         # ensure gc thread is done
16144         for i in $(mdts_nodes); do
16145                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16146                         error "$i: GC-thread not done"
16147         done
16148
16149         local first_rec
16150         for (( i = 1; i <= MDSCOUNT; i++ )); do
16151                 # check cl_user1 still registered
16152                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16153                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16154                 # check cl_user2 unregistered
16155                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16156                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16157
16158                 # check changelogs are present and starting at $user_rec1 + 1
16159                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16160                 [ -n "$user_rec1" ] ||
16161                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16162                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16163                             awk '{ print $1; exit; }')
16164
16165                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16166                 [ $((user_rec1 + 1)) == $first_rec ] ||
16167                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16168         done
16169 }
16170 run_test 160f "changelog garbage collect (timestamped users)"
16171
16172 test_160g() {
16173         remote_mds_nodsh && skip "remote MDS with nodsh"
16174         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16175                 skip "Need MDS version at least 2.14.55"
16176
16177         local mdts=$(comma_list $(mdts_nodes))
16178
16179         # Create a user
16180         changelog_register || error "first changelog_register failed"
16181         changelog_register || error "second changelog_register failed"
16182         local cl_users
16183         declare -A cl_user1
16184         declare -A cl_user2
16185         local user_rec1
16186         local user_rec2
16187         local i
16188
16189         # generate some changelog records to accumulate on each MDT
16190         # use all_char because created files should be evenly distributed
16191         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16192                 error "test_mkdir $tdir failed"
16193         for ((i = 0; i < MDSCOUNT; i++)); do
16194                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16195                         error "create $DIR/$tdir/d$i.1 failed"
16196         done
16197
16198         # check changelogs have been generated
16199         local nbcl=$(changelog_dump | wc -l)
16200         (( $nbcl > 0 )) || error "no changelogs found"
16201
16202         # reduce the max_idle_indexes value to make sure we exceed it
16203         for param in "changelog_max_idle_indexes=2" \
16204                      "changelog_gc=1" \
16205                      "changelog_min_gc_interval=2"; do
16206                 local MDT0=$(facet_svc $SINGLEMDS)
16207                 local var="${param%=*}"
16208                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16209
16210                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16211                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16212                         error "unable to set mdd.*.$param"
16213         done
16214
16215         local start=$SECONDS
16216         for i in $(seq $MDSCOUNT); do
16217                 cl_users=(${CL_USERS[mds$i]})
16218                 cl_user1[mds$i]="${cl_users[0]}"
16219                 cl_user2[mds$i]="${cl_users[1]}"
16220
16221                 [ -n "${cl_user1[mds$i]}" ] ||
16222                         error "mds$i: user1 is not registered"
16223                 [ -n "${cl_user2[mds$i]}" ] ||
16224                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16225
16226                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16227                 [ -n "$user_rec1" ] ||
16228                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16229                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16230                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16231                 [ -n "$user_rec2" ] ||
16232                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16233                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16234                      "$user_rec1 + 2 == $user_rec2"
16235                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16236                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16237                               "expected $user_rec1 + 2, but is $user_rec2"
16238                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16239                 [ -n "$user_rec2" ] ||
16240                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16241                 [ $user_rec1 == $user_rec2 ] ||
16242                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16243                               "expected $user_rec1, but is $user_rec2"
16244         done
16245
16246         # ensure we are past the previous changelog_min_gc_interval set above
16247         local sleep2=$((start + 2 - SECONDS))
16248         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16249         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16250         # cl_user1 should be OK because it recently processed records.
16251         for ((i = 0; i < MDSCOUNT; i++)); do
16252                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16253                         error "create $DIR/$tdir/d$i.3 failed"
16254         done
16255
16256         # ensure gc thread is done
16257         for i in $(mdts_nodes); do
16258                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16259                         error "$i: GC-thread not done"
16260         done
16261
16262         local first_rec
16263         for (( i = 1; i <= MDSCOUNT; i++ )); do
16264                 # check cl_user1 still registered
16265                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16266                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16267                 # check cl_user2 unregistered
16268                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16269                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16270
16271                 # check changelogs are present and starting at $user_rec1 + 1
16272                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16273                 [ -n "$user_rec1" ] ||
16274                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16275                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16276                             awk '{ print $1; exit; }')
16277
16278                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16279                 [ $((user_rec1 + 1)) == $first_rec ] ||
16280                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16281         done
16282 }
16283 run_test 160g "changelog garbage collect on idle records"
16284
16285 test_160h() {
16286         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16287         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16288                 skip "Need MDS version at least 2.10.56"
16289
16290         local mdts=$(comma_list $(mdts_nodes))
16291
16292         # Create a user
16293         changelog_register || error "first changelog_register failed"
16294         changelog_register || error "second changelog_register failed"
16295         local cl_users
16296         declare -A cl_user1
16297         declare -A cl_user2
16298         local user_rec1
16299         local user_rec2
16300         local i
16301
16302         # generate some changelog records to accumulate on each MDT
16303         # use all_char because created files should be evenly distributed
16304         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16305                 error "test_mkdir $tdir failed"
16306         for ((i = 0; i < MDSCOUNT; i++)); do
16307                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16308                         error "create $DIR/$tdir/d$i.1 failed"
16309         done
16310
16311         # check changelogs have been generated
16312         local nbcl=$(changelog_dump | wc -l)
16313         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16314
16315         for param in "changelog_max_idle_time=10" \
16316                      "changelog_gc=1" \
16317                      "changelog_min_gc_interval=2"; do
16318                 local MDT0=$(facet_svc $SINGLEMDS)
16319                 local var="${param%=*}"
16320                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16321
16322                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16323                 do_nodes $mdts $LCTL set_param mdd.*.$param
16324         done
16325
16326         # force cl_user2 to be idle (1st part)
16327         sleep 9
16328
16329         for i in $(seq $MDSCOUNT); do
16330                 cl_users=(${CL_USERS[mds$i]})
16331                 cl_user1[mds$i]="${cl_users[0]}"
16332                 cl_user2[mds$i]="${cl_users[1]}"
16333
16334                 [ -n "${cl_user1[mds$i]}" ] ||
16335                         error "mds$i: no user registered"
16336                 [ -n "${cl_user2[mds$i]}" ] ||
16337                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16338
16339                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16340                 [ -n "$user_rec1" ] ||
16341                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16342                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16343                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16344                 [ -n "$user_rec2" ] ||
16345                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16346                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16347                      "$user_rec1 + 2 == $user_rec2"
16348                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16349                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16350                               "$user_rec1 + 2, but is $user_rec2"
16351                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16352                 [ -n "$user_rec2" ] ||
16353                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16354                 [ $user_rec1 == $user_rec2 ] ||
16355                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16356                               "$user_rec1, but is $user_rec2"
16357         done
16358
16359         # force cl_user2 to be idle (2nd part) and to reach
16360         # changelog_max_idle_time
16361         sleep 2
16362
16363         # force each GC-thread start and block then
16364         # one per MDT/MDD, set fail_val accordingly
16365         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16366         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16367
16368         # generate more changelogs to trigger fail_loc
16369         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16370                 error "create $DIR/$tdir/${tfile}bis failed"
16371
16372         # stop MDT to stop GC-thread, should be done in back-ground as it will
16373         # block waiting for the thread to be released and exit
16374         declare -A stop_pids
16375         for i in $(seq $MDSCOUNT); do
16376                 stop mds$i &
16377                 stop_pids[mds$i]=$!
16378         done
16379
16380         for i in $(mdts_nodes); do
16381                 local facet
16382                 local nb=0
16383                 local facets=$(facets_up_on_host $i)
16384
16385                 for facet in ${facets//,/ }; do
16386                         if [[ $facet == mds* ]]; then
16387                                 nb=$((nb + 1))
16388                         fi
16389                 done
16390                 # ensure each MDS's gc threads are still present and all in "R"
16391                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16392                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16393                         error "$i: expected $nb GC-thread"
16394                 wait_update $i \
16395                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16396                         "R" 20 ||
16397                         error "$i: GC-thread not found in R-state"
16398                 # check umounts of each MDT on MDS have reached kthread_stop()
16399                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16400                         error "$i: expected $nb umount"
16401                 wait_update $i \
16402                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16403                         error "$i: umount not found in D-state"
16404         done
16405
16406         # release all GC-threads
16407         do_nodes $mdts $LCTL set_param fail_loc=0
16408
16409         # wait for MDT stop to complete
16410         for i in $(seq $MDSCOUNT); do
16411                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16412         done
16413
16414         # XXX
16415         # may try to check if any orphan changelog records are present
16416         # via ldiskfs/zfs and llog_reader...
16417
16418         # re-start/mount MDTs
16419         for i in $(seq $MDSCOUNT); do
16420                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16421                         error "Fail to start mds$i"
16422         done
16423
16424         local first_rec
16425         for i in $(seq $MDSCOUNT); do
16426                 # check cl_user1 still registered
16427                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16428                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16429                 # check cl_user2 unregistered
16430                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16431                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16432
16433                 # check changelogs are present and starting at $user_rec1 + 1
16434                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16435                 [ -n "$user_rec1" ] ||
16436                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16437                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16438                             awk '{ print $1; exit; }')
16439
16440                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16441                 [ $((user_rec1 + 1)) == $first_rec ] ||
16442                         error "mds$i: first index should be $user_rec1 + 1, " \
16443                               "but is $first_rec"
16444         done
16445 }
16446 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16447               "during mount"
16448
16449 test_160i() {
16450
16451         local mdts=$(comma_list $(mdts_nodes))
16452
16453         changelog_register || error "first changelog_register failed"
16454
16455         # generate some changelog records to accumulate on each MDT
16456         # use all_char because created files should be evenly distributed
16457         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16458                 error "test_mkdir $tdir failed"
16459         for ((i = 0; i < MDSCOUNT; i++)); do
16460                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16461                         error "create $DIR/$tdir/d$i.1 failed"
16462         done
16463
16464         # check changelogs have been generated
16465         local nbcl=$(changelog_dump | wc -l)
16466         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16467
16468         # simulate race between register and unregister
16469         # XXX as fail_loc is set per-MDS, with DNE configs the race
16470         # simulation will only occur for one MDT per MDS and for the
16471         # others the normal race scenario will take place
16472         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16473         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16474         do_nodes $mdts $LCTL set_param fail_val=1
16475
16476         # unregister 1st user
16477         changelog_deregister &
16478         local pid1=$!
16479         # wait some time for deregister work to reach race rdv
16480         sleep 2
16481         # register 2nd user
16482         changelog_register || error "2nd user register failed"
16483
16484         wait $pid1 || error "1st user deregister failed"
16485
16486         local i
16487         local last_rec
16488         declare -A LAST_REC
16489         for i in $(seq $MDSCOUNT); do
16490                 if changelog_users mds$i | grep "^cl"; then
16491                         # make sure new records are added with one user present
16492                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16493                                           awk '/^current.index:/ { print $NF }')
16494                 else
16495                         error "mds$i has no user registered"
16496                 fi
16497         done
16498
16499         # generate more changelog records to accumulate on each MDT
16500         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16501                 error "create $DIR/$tdir/${tfile}bis failed"
16502
16503         for i in $(seq $MDSCOUNT); do
16504                 last_rec=$(changelog_users $SINGLEMDS |
16505                            awk '/^current.index:/ { print $NF }')
16506                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16507                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16508                         error "changelogs are off on mds$i"
16509         done
16510 }
16511 run_test 160i "changelog user register/unregister race"
16512
16513 test_160j() {
16514         remote_mds_nodsh && skip "remote MDS with nodsh"
16515         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16516                 skip "Need MDS version at least 2.12.56"
16517
16518         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16519         stack_trap "umount $MOUNT2" EXIT
16520
16521         changelog_register || error "first changelog_register failed"
16522         stack_trap "changelog_deregister" EXIT
16523
16524         # generate some changelog
16525         # use all_char because created files should be evenly distributed
16526         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16527                 error "mkdir $tdir failed"
16528         for ((i = 0; i < MDSCOUNT; i++)); do
16529                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16530                         error "create $DIR/$tdir/d$i.1 failed"
16531         done
16532
16533         # open the changelog device
16534         exec 3>/dev/changelog-$FSNAME-MDT0000
16535         stack_trap "exec 3>&-" EXIT
16536         exec 4</dev/changelog-$FSNAME-MDT0000
16537         stack_trap "exec 4<&-" EXIT
16538
16539         # umount the first lustre mount
16540         umount $MOUNT
16541         stack_trap "mount_client $MOUNT" EXIT
16542
16543         # read changelog, which may or may not fail, but should not crash
16544         cat <&4 >/dev/null
16545
16546         # clear changelog
16547         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16548         changelog_users $SINGLEMDS | grep -q $cl_user ||
16549                 error "User $cl_user not found in changelog_users"
16550
16551         printf 'clear:'$cl_user':0' >&3
16552 }
16553 run_test 160j "client can be umounted while its chanangelog is being used"
16554
16555 test_160k() {
16556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16557         remote_mds_nodsh && skip "remote MDS with nodsh"
16558
16559         mkdir -p $DIR/$tdir/1/1
16560
16561         changelog_register || error "changelog_register failed"
16562         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16563
16564         changelog_users $SINGLEMDS | grep -q $cl_user ||
16565                 error "User '$cl_user' not found in changelog_users"
16566 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16567         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16568         rmdir $DIR/$tdir/1/1 & sleep 1
16569         mkdir $DIR/$tdir/2
16570         touch $DIR/$tdir/2/2
16571         rm -rf $DIR/$tdir/2
16572
16573         wait
16574         sleep 4
16575
16576         changelog_dump | grep rmdir || error "rmdir not recorded"
16577 }
16578 run_test 160k "Verify that changelog records are not lost"
16579
16580 # Verifies that a file passed as a parameter has recently had an operation
16581 # performed on it that has generated an MTIME changelog which contains the
16582 # correct parent FID. As files might reside on a different MDT from the
16583 # parent directory in DNE configurations, the FIDs are translated to paths
16584 # before being compared, which should be identical
16585 compare_mtime_changelog() {
16586         local file="${1}"
16587         local mdtidx
16588         local mtime
16589         local cl_fid
16590         local pdir
16591         local dir
16592
16593         mdtidx=$($LFS getstripe --mdt-index $file)
16594         mdtidx=$(printf "%04x" $mdtidx)
16595
16596         # Obtain the parent FID from the MTIME changelog
16597         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16598         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16599
16600         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16601         [ -z "$cl_fid" ] && error "parent FID not present"
16602
16603         # Verify that the path for the parent FID is the same as the path for
16604         # the test directory
16605         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16606
16607         dir=$(dirname $1)
16608
16609         [[ "${pdir%/}" == "$dir" ]] ||
16610                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16611 }
16612
16613 test_160l() {
16614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16615
16616         remote_mds_nodsh && skip "remote MDS with nodsh"
16617         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16618                 skip "Need MDS version at least 2.13.55"
16619
16620         local cl_user
16621
16622         changelog_register || error "changelog_register failed"
16623         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16624
16625         changelog_users $SINGLEMDS | grep -q $cl_user ||
16626                 error "User '$cl_user' not found in changelog_users"
16627
16628         # Clear some types so that MTIME changelogs are generated
16629         changelog_chmask "-CREAT"
16630         changelog_chmask "-CLOSE"
16631
16632         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16633
16634         # Test CL_MTIME during setattr
16635         touch $DIR/$tdir/$tfile
16636         compare_mtime_changelog $DIR/$tdir/$tfile
16637
16638         # Test CL_MTIME during close
16639         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16640         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16641 }
16642 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16643
16644 test_160m() {
16645         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16646         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16647                 skip "Need MDS version at least 2.14.51"
16648         local cl_users
16649         local cl_user1
16650         local cl_user2
16651         local pid1
16652
16653         # Create a user
16654         changelog_register || error "first changelog_register failed"
16655         changelog_register || error "second changelog_register failed"
16656
16657         cl_users=(${CL_USERS[mds1]})
16658         cl_user1="${cl_users[0]}"
16659         cl_user2="${cl_users[1]}"
16660         # generate some changelog records to accumulate on MDT0
16661         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16662         createmany -m $DIR/$tdir/$tfile 50 ||
16663                 error "create $DIR/$tdir/$tfile failed"
16664         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16665         rm -f $DIR/$tdir
16666
16667         # check changelogs have been generated
16668         local nbcl=$(changelog_dump | wc -l)
16669         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16670
16671 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16672         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16673
16674         __changelog_clear mds1 $cl_user1 +10
16675         __changelog_clear mds1 $cl_user2 0 &
16676         pid1=$!
16677         sleep 2
16678         __changelog_clear mds1 $cl_user1 0 ||
16679                 error "fail to cancel record for $cl_user1"
16680         wait $pid1
16681         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16682 }
16683 run_test 160m "Changelog clear race"
16684
16685 test_160n() {
16686         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16687         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16688                 skip "Need MDS version at least 2.14.51"
16689         local cl_users
16690         local cl_user1
16691         local cl_user2
16692         local pid1
16693         local first_rec
16694         local last_rec=0
16695
16696         # Create a user
16697         changelog_register || error "first changelog_register failed"
16698
16699         cl_users=(${CL_USERS[mds1]})
16700         cl_user1="${cl_users[0]}"
16701
16702         # generate some changelog records to accumulate on MDT0
16703         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16704         first_rec=$(changelog_users $SINGLEMDS |
16705                         awk '/^current.index:/ { print $NF }')
16706         while (( last_rec < (( first_rec + 65000)) )); do
16707                 createmany -m $DIR/$tdir/$tfile 10000 ||
16708                         error "create $DIR/$tdir/$tfile failed"
16709
16710                 for i in $(seq 0 10000); do
16711                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16712                                 > /dev/null
16713                 done
16714
16715                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16716                         error "unlinkmany failed unlink"
16717                 last_rec=$(changelog_users $SINGLEMDS |
16718                         awk '/^current.index:/ { print $NF }')
16719                 echo last record $last_rec
16720                 (( last_rec == 0 )) && error "no changelog found"
16721         done
16722
16723 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16724         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16725
16726         __changelog_clear mds1 $cl_user1 0 &
16727         pid1=$!
16728         sleep 2
16729         __changelog_clear mds1 $cl_user1 0 ||
16730                 error "fail to cancel record for $cl_user1"
16731         wait $pid1
16732         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16733 }
16734 run_test 160n "Changelog destroy race"
16735
16736 test_160o() {
16737         local mdt="$(facet_svc $SINGLEMDS)"
16738
16739         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16740         remote_mds_nodsh && skip "remote MDS with nodsh"
16741         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16742                 skip "Need MDS version at least 2.14.52"
16743
16744         changelog_register --user test_160o -m unlnk+close+open ||
16745                 error "changelog_register failed"
16746
16747         do_facet $SINGLEMDS $LCTL --device $mdt \
16748                                 changelog_register -u "Tt3_-#" &&
16749                 error "bad symbols in name should fail"
16750
16751         do_facet $SINGLEMDS $LCTL --device $mdt \
16752                                 changelog_register -u test_160o &&
16753                 error "the same name registration should fail"
16754
16755         do_facet $SINGLEMDS $LCTL --device $mdt \
16756                         changelog_register -u test_160toolongname &&
16757                 error "too long name registration should fail"
16758
16759         changelog_chmask "MARK+HSM"
16760         lctl get_param mdd.*.changelog*mask
16761         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16762         changelog_users $SINGLEMDS | grep -q $cl_user ||
16763                 error "User $cl_user not found in changelog_users"
16764         #verify username
16765         echo $cl_user | grep -q test_160o ||
16766                 error "User $cl_user has no specific name 'test160o'"
16767
16768         # change something
16769         changelog_clear 0 || error "changelog_clear failed"
16770         # generate some changelog records to accumulate on MDT0
16771         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16772         touch $DIR/$tdir/$tfile                 # open 1
16773
16774         OPENS=$(changelog_dump | grep -c "OPEN")
16775         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16776
16777         # must be no MKDIR it wasn't set as user mask
16778         MKDIR=$(changelog_dump | grep -c "MKDIR")
16779         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16780
16781         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16782                                 mdd.$mdt.changelog_current_mask -n)
16783         # register maskless user
16784         changelog_register || error "changelog_register failed"
16785         # effective mask should be not changed because it is not minimal
16786         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16787                                 mdd.$mdt.changelog_current_mask -n)
16788         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16789         # set server mask to minimal value
16790         changelog_chmask "MARK"
16791         # check effective mask again, should be treated as DEFMASK now
16792         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16793                                 mdd.$mdt.changelog_current_mask -n)
16794         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16795
16796         do_facet $SINGLEMDS $LCTL --device $mdt \
16797                                 changelog_deregister -u test_160o ||
16798                 error "cannot deregister by name"
16799 }
16800 run_test 160o "changelog user name and mask"
16801
16802 test_160p() {
16803         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16804         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16805                 skip "Need MDS version at least 2.14.51"
16806         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16807         local cl_users
16808         local cl_user1
16809         local entry_count
16810
16811         # Create a user
16812         changelog_register || error "first changelog_register failed"
16813
16814         cl_users=(${CL_USERS[mds1]})
16815         cl_user1="${cl_users[0]}"
16816
16817         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16818         createmany -m $DIR/$tdir/$tfile 50 ||
16819                 error "create $DIR/$tdir/$tfile failed"
16820         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16821         rm -rf $DIR/$tdir
16822
16823         # check changelogs have been generated
16824         entry_count=$(changelog_dump | wc -l)
16825         ((entry_count != 0)) || error "no changelog entries found"
16826
16827         # remove changelog_users and check that orphan entries are removed
16828         stop mds1
16829         local dev=$(mdsdevname 1)
16830         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16831         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16832         entry_count=$(changelog_dump | wc -l)
16833         ((entry_count == 0)) ||
16834                 error "found $entry_count changelog entries, expected none"
16835 }
16836 run_test 160p "Changelog orphan cleanup with no users"
16837
16838 test_160q() {
16839         local mdt="$(facet_svc $SINGLEMDS)"
16840         local clu
16841
16842         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16843         remote_mds_nodsh && skip "remote MDS with nodsh"
16844         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16845                 skip "Need MDS version at least 2.14.54"
16846
16847         # set server mask to minimal value like server init does
16848         changelog_chmask "MARK"
16849         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16850                 error "changelog_register failed"
16851         # check effective mask again, should be treated as DEFMASK now
16852         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16853                                 mdd.$mdt.changelog_current_mask -n)
16854         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16855                 error "changelog_deregister failed"
16856         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16857 }
16858 run_test 160q "changelog effective mask is DEFMASK if not set"
16859
16860 test_160s() {
16861         remote_mds_nodsh && skip "remote MDS with nodsh"
16862         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16863                 skip "Need MDS version at least 2.14.55"
16864
16865         local mdts=$(comma_list $(mdts_nodes))
16866
16867         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16868         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16869                                        fail_val=$((24 * 3600 * 10))
16870
16871         # Create a user which is 10 days old
16872         changelog_register || error "first changelog_register failed"
16873         local cl_users
16874         declare -A cl_user1
16875         local i
16876
16877         # generate some changelog records to accumulate on each MDT
16878         # use all_char because created files should be evenly distributed
16879         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16880                 error "test_mkdir $tdir failed"
16881         for ((i = 0; i < MDSCOUNT; i++)); do
16882                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16883                         error "create $DIR/$tdir/d$i.1 failed"
16884         done
16885
16886         # check changelogs have been generated
16887         local nbcl=$(changelog_dump | wc -l)
16888         (( nbcl > 0 )) || error "no changelogs found"
16889
16890         # reduce the max_idle_indexes value to make sure we exceed it
16891         for param in "changelog_max_idle_indexes=2097446912" \
16892                      "changelog_max_idle_time=2592000" \
16893                      "changelog_gc=1" \
16894                      "changelog_min_gc_interval=2"; do
16895                 local MDT0=$(facet_svc $SINGLEMDS)
16896                 local var="${param%=*}"
16897                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16898
16899                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16900                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16901                         error "unable to set mdd.*.$param"
16902         done
16903
16904         local start=$SECONDS
16905         for i in $(seq $MDSCOUNT); do
16906                 cl_users=(${CL_USERS[mds$i]})
16907                 cl_user1[mds$i]="${cl_users[0]}"
16908
16909                 [[ -n "${cl_user1[mds$i]}" ]] ||
16910                         error "mds$i: no user registered"
16911         done
16912
16913         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16914         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16915
16916         # ensure we are past the previous changelog_min_gc_interval set above
16917         local sleep2=$((start + 2 - SECONDS))
16918         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16919
16920         # Generate one more changelog to trigger GC
16921         for ((i = 0; i < MDSCOUNT; i++)); do
16922                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16923                         error "create $DIR/$tdir/d$i.3 failed"
16924         done
16925
16926         # ensure gc thread is done
16927         for node in $(mdts_nodes); do
16928                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16929                         error "$node: GC-thread not done"
16930         done
16931
16932         do_nodes $mdts $LCTL set_param fail_loc=0
16933
16934         for (( i = 1; i <= MDSCOUNT; i++ )); do
16935                 # check cl_user1 is purged
16936                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16937                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16938         done
16939         return 0
16940 }
16941 run_test 160s "changelog garbage collect on idle records * time"
16942
16943 test_161a() {
16944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16945
16946         test_mkdir -c1 $DIR/$tdir
16947         cp /etc/hosts $DIR/$tdir/$tfile
16948         test_mkdir -c1 $DIR/$tdir/foo1
16949         test_mkdir -c1 $DIR/$tdir/foo2
16950         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16951         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16952         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16953         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16954         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16955         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16956                 $LFS fid2path $DIR $FID
16957                 error "bad link ea"
16958         fi
16959         # middle
16960         rm $DIR/$tdir/foo2/zachary
16961         # last
16962         rm $DIR/$tdir/foo2/thor
16963         # first
16964         rm $DIR/$tdir/$tfile
16965         # rename
16966         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16967         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16968                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16969         rm $DIR/$tdir/foo2/maggie
16970
16971         # overflow the EA
16972         local longname=$tfile.avg_len_is_thirty_two_
16973         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16974                 error_noexit 'failed to unlink many hardlinks'" EXIT
16975         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16976                 error "failed to hardlink many files"
16977         links=$($LFS fid2path $DIR $FID | wc -l)
16978         echo -n "${links}/1000 links in link EA"
16979         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16980 }
16981 run_test 161a "link ea sanity"
16982
16983 test_161b() {
16984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16985         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16986
16987         local MDTIDX=1
16988         local remote_dir=$DIR/$tdir/remote_dir
16989
16990         mkdir -p $DIR/$tdir
16991         $LFS mkdir -i $MDTIDX $remote_dir ||
16992                 error "create remote directory failed"
16993
16994         cp /etc/hosts $remote_dir/$tfile
16995         mkdir -p $remote_dir/foo1
16996         mkdir -p $remote_dir/foo2
16997         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16998         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16999         ln $remote_dir/$tfile $remote_dir/foo1/luna
17000         ln $remote_dir/$tfile $remote_dir/foo2/thor
17001
17002         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17003                      tr -d ']')
17004         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17005                 $LFS fid2path $DIR $FID
17006                 error "bad link ea"
17007         fi
17008         # middle
17009         rm $remote_dir/foo2/zachary
17010         # last
17011         rm $remote_dir/foo2/thor
17012         # first
17013         rm $remote_dir/$tfile
17014         # rename
17015         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17016         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17017         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17018                 $LFS fid2path $DIR $FID
17019                 error "bad link rename"
17020         fi
17021         rm $remote_dir/foo2/maggie
17022
17023         # overflow the EA
17024         local longname=filename_avg_len_is_thirty_two_
17025         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17026                 error "failed to hardlink many files"
17027         links=$($LFS fid2path $DIR $FID | wc -l)
17028         echo -n "${links}/1000 links in link EA"
17029         [[ ${links} -gt 60 ]] ||
17030                 error "expected at least 60 links in link EA"
17031         unlinkmany $remote_dir/foo2/$longname 1000 ||
17032         error "failed to unlink many hardlinks"
17033 }
17034 run_test 161b "link ea sanity under remote directory"
17035
17036 test_161c() {
17037         remote_mds_nodsh && skip "remote MDS with nodsh"
17038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17039         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17040                 skip "Need MDS version at least 2.1.5"
17041
17042         # define CLF_RENAME_LAST 0x0001
17043         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17044         changelog_register || error "changelog_register failed"
17045
17046         rm -rf $DIR/$tdir
17047         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17048         touch $DIR/$tdir/foo_161c
17049         touch $DIR/$tdir/bar_161c
17050         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17051         changelog_dump | grep RENME | tail -n 5
17052         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17053         changelog_clear 0 || error "changelog_clear failed"
17054         if [ x$flags != "x0x1" ]; then
17055                 error "flag $flags is not 0x1"
17056         fi
17057
17058         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17059         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17060         touch $DIR/$tdir/foo_161c
17061         touch $DIR/$tdir/bar_161c
17062         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17063         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17064         changelog_dump | grep RENME | tail -n 5
17065         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17066         changelog_clear 0 || error "changelog_clear failed"
17067         if [ x$flags != "x0x0" ]; then
17068                 error "flag $flags is not 0x0"
17069         fi
17070         echo "rename overwrite a target having nlink > 1," \
17071                 "changelog record has flags of $flags"
17072
17073         # rename doesn't overwrite a target (changelog flag 0x0)
17074         touch $DIR/$tdir/foo_161c
17075         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17076         changelog_dump | grep RENME | tail -n 5
17077         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17078         changelog_clear 0 || error "changelog_clear failed"
17079         if [ x$flags != "x0x0" ]; then
17080                 error "flag $flags is not 0x0"
17081         fi
17082         echo "rename doesn't overwrite a target," \
17083                 "changelog record has flags of $flags"
17084
17085         # define CLF_UNLINK_LAST 0x0001
17086         # unlink a file having nlink = 1 (changelog flag 0x1)
17087         rm -f $DIR/$tdir/foo2_161c
17088         changelog_dump | grep UNLNK | tail -n 5
17089         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17090         changelog_clear 0 || error "changelog_clear failed"
17091         if [ x$flags != "x0x1" ]; then
17092                 error "flag $flags is not 0x1"
17093         fi
17094         echo "unlink a file having nlink = 1," \
17095                 "changelog record has flags of $flags"
17096
17097         # unlink a file having nlink > 1 (changelog flag 0x0)
17098         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17099         rm -f $DIR/$tdir/foobar_161c
17100         changelog_dump | grep UNLNK | tail -n 5
17101         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17102         changelog_clear 0 || error "changelog_clear failed"
17103         if [ x$flags != "x0x0" ]; then
17104                 error "flag $flags is not 0x0"
17105         fi
17106         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17107 }
17108 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17109
17110 test_161d() {
17111         remote_mds_nodsh && skip "remote MDS with nodsh"
17112         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17113
17114         local pid
17115         local fid
17116
17117         changelog_register || error "changelog_register failed"
17118
17119         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17120         # interfer with $MOUNT/.lustre/fid/ access
17121         mkdir $DIR/$tdir
17122         [[ $? -eq 0 ]] || error "mkdir failed"
17123
17124         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17125         $LCTL set_param fail_loc=0x8000140c
17126         # 5s pause
17127         $LCTL set_param fail_val=5
17128
17129         # create file
17130         echo foofoo > $DIR/$tdir/$tfile &
17131         pid=$!
17132
17133         # wait for create to be delayed
17134         sleep 2
17135
17136         ps -p $pid
17137         [[ $? -eq 0 ]] || error "create should be blocked"
17138
17139         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17140         stack_trap "rm -f $tempfile"
17141         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17142         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17143         # some delay may occur during ChangeLog publishing and file read just
17144         # above, that could allow file write to happen finally
17145         [[ -s $tempfile ]] && echo "file should be empty"
17146
17147         $LCTL set_param fail_loc=0
17148
17149         wait $pid
17150         [[ $? -eq 0 ]] || error "create failed"
17151 }
17152 run_test 161d "create with concurrent .lustre/fid access"
17153
17154 check_path() {
17155         local expected="$1"
17156         shift
17157         local fid="$2"
17158
17159         local path
17160         path=$($LFS fid2path "$@")
17161         local rc=$?
17162
17163         if [ $rc -ne 0 ]; then
17164                 error "path looked up of '$expected' failed: rc=$rc"
17165         elif [ "$path" != "$expected" ]; then
17166                 error "path looked up '$path' instead of '$expected'"
17167         else
17168                 echo "FID '$fid' resolves to path '$path' as expected"
17169         fi
17170 }
17171
17172 test_162a() { # was test_162
17173         test_mkdir -p -c1 $DIR/$tdir/d2
17174         touch $DIR/$tdir/d2/$tfile
17175         touch $DIR/$tdir/d2/x1
17176         touch $DIR/$tdir/d2/x2
17177         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17178         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17179         # regular file
17180         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17181         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17182
17183         # softlink
17184         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17185         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17186         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17187
17188         # softlink to wrong file
17189         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17190         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17191         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17192
17193         # hardlink
17194         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17195         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17196         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17197         # fid2path dir/fsname should both work
17198         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17199         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17200
17201         # hardlink count: check that there are 2 links
17202         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17203         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17204
17205         # hardlink indexing: remove the first link
17206         rm $DIR/$tdir/d2/p/q/r/hlink
17207         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17208 }
17209 run_test 162a "path lookup sanity"
17210
17211 test_162b() {
17212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17213         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17214
17215         mkdir $DIR/$tdir
17216         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17217                                 error "create striped dir failed"
17218
17219         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17220                                         tail -n 1 | awk '{print $2}')
17221         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17222
17223         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17224         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17225
17226         # regular file
17227         for ((i=0;i<5;i++)); do
17228                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17229                         error "get fid for f$i failed"
17230                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17231
17232                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17233                         error "get fid for d$i failed"
17234                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17235         done
17236
17237         return 0
17238 }
17239 run_test 162b "striped directory path lookup sanity"
17240
17241 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17242 test_162c() {
17243         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17244                 skip "Need MDS version at least 2.7.51"
17245
17246         local lpath=$tdir.local
17247         local rpath=$tdir.remote
17248
17249         test_mkdir $DIR/$lpath
17250         test_mkdir $DIR/$rpath
17251
17252         for ((i = 0; i <= 101; i++)); do
17253                 lpath="$lpath/$i"
17254                 mkdir $DIR/$lpath
17255                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17256                         error "get fid for local directory $DIR/$lpath failed"
17257                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17258
17259                 rpath="$rpath/$i"
17260                 test_mkdir $DIR/$rpath
17261                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17262                         error "get fid for remote directory $DIR/$rpath failed"
17263                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17264         done
17265
17266         return 0
17267 }
17268 run_test 162c "fid2path works with paths 100 or more directories deep"
17269
17270 oalr_event_count() {
17271         local event="${1}"
17272         local trace="${2}"
17273
17274         awk -v name="${FSNAME}-OST0000" \
17275             -v event="${event}" \
17276             '$1 == "TRACE" && $2 == event && $3 == name' \
17277             "${trace}" |
17278         wc -l
17279 }
17280
17281 oalr_expect_event_count() {
17282         local event="${1}"
17283         local trace="${2}"
17284         local expect="${3}"
17285         local count
17286
17287         count=$(oalr_event_count "${event}" "${trace}")
17288         if ((count == expect)); then
17289                 return 0
17290         fi
17291
17292         error_noexit "${event} event count was '${count}', expected ${expect}"
17293         cat "${trace}" >&2
17294         exit 1
17295 }
17296
17297 cleanup_165() {
17298         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17299         stop ost1
17300         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17301 }
17302
17303 setup_165() {
17304         sync # Flush previous IOs so we can count log entries.
17305         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17306         stack_trap cleanup_165 EXIT
17307 }
17308
17309 test_165a() {
17310         local trace="/tmp/${tfile}.trace"
17311         local rc
17312         local count
17313
17314         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17315                 skip "OFD access log unsupported"
17316
17317         setup_165
17318         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17319         sleep 5
17320
17321         do_facet ost1 ofd_access_log_reader --list
17322         stop ost1
17323
17324         do_facet ost1 killall -TERM ofd_access_log_reader
17325         wait
17326         rc=$?
17327
17328         if ((rc != 0)); then
17329                 error "ofd_access_log_reader exited with rc = '${rc}'"
17330         fi
17331
17332         # Parse trace file for discovery events:
17333         oalr_expect_event_count alr_log_add "${trace}" 1
17334         oalr_expect_event_count alr_log_eof "${trace}" 1
17335         oalr_expect_event_count alr_log_free "${trace}" 1
17336 }
17337 run_test 165a "ofd access log discovery"
17338
17339 test_165b() {
17340         local trace="/tmp/${tfile}.trace"
17341         local file="${DIR}/${tfile}"
17342         local pfid1
17343         local pfid2
17344         local -a entry
17345         local rc
17346         local count
17347         local size
17348         local flags
17349
17350         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17351                 skip "OFD access log unsupported"
17352
17353         setup_165
17354         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17355         sleep 5
17356
17357         do_facet ost1 ofd_access_log_reader --list
17358
17359         lfs setstripe -c 1 -i 0 "${file}"
17360         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17361                 error "cannot create '${file}'"
17362
17363         sleep 5
17364         do_facet ost1 killall -TERM ofd_access_log_reader
17365         wait
17366         rc=$?
17367
17368         if ((rc != 0)); then
17369                 error "ofd_access_log_reader exited with rc = '${rc}'"
17370         fi
17371
17372         oalr_expect_event_count alr_log_entry "${trace}" 1
17373
17374         pfid1=$($LFS path2fid "${file}")
17375
17376         # 1     2             3   4    5     6   7    8    9     10
17377         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17378         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17379
17380         echo "entry = '${entry[*]}'" >&2
17381
17382         pfid2=${entry[4]}
17383         if [[ "${pfid1}" != "${pfid2}" ]]; then
17384                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17385         fi
17386
17387         size=${entry[8]}
17388         if ((size != 1048576)); then
17389                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17390         fi
17391
17392         flags=${entry[10]}
17393         if [[ "${flags}" != "w" ]]; then
17394                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17395         fi
17396
17397         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17398         sleep 5
17399
17400         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17401                 error "cannot read '${file}'"
17402         sleep 5
17403
17404         do_facet ost1 killall -TERM ofd_access_log_reader
17405         wait
17406         rc=$?
17407
17408         if ((rc != 0)); then
17409                 error "ofd_access_log_reader exited with rc = '${rc}'"
17410         fi
17411
17412         oalr_expect_event_count alr_log_entry "${trace}" 1
17413
17414         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17415         echo "entry = '${entry[*]}'" >&2
17416
17417         pfid2=${entry[4]}
17418         if [[ "${pfid1}" != "${pfid2}" ]]; then
17419                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17420         fi
17421
17422         size=${entry[8]}
17423         if ((size != 524288)); then
17424                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17425         fi
17426
17427         flags=${entry[10]}
17428         if [[ "${flags}" != "r" ]]; then
17429                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17430         fi
17431 }
17432 run_test 165b "ofd access log entries are produced and consumed"
17433
17434 test_165c() {
17435         local trace="/tmp/${tfile}.trace"
17436         local file="${DIR}/${tdir}/${tfile}"
17437
17438         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17439                 skip "OFD access log unsupported"
17440
17441         test_mkdir "${DIR}/${tdir}"
17442
17443         setup_165
17444         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17445         sleep 5
17446
17447         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17448
17449         # 4096 / 64 = 64. Create twice as many entries.
17450         for ((i = 0; i < 128; i++)); do
17451                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17452                         error "cannot create file"
17453         done
17454
17455         sync
17456
17457         do_facet ost1 killall -TERM ofd_access_log_reader
17458         wait
17459         rc=$?
17460         if ((rc != 0)); then
17461                 error "ofd_access_log_reader exited with rc = '${rc}'"
17462         fi
17463
17464         unlinkmany  "${file}-%d" 128
17465 }
17466 run_test 165c "full ofd access logs do not block IOs"
17467
17468 oal_get_read_count() {
17469         local stats="$1"
17470
17471         # STATS lustre-OST0001 alr_read_count 1
17472
17473         do_facet ost1 cat "${stats}" |
17474         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17475              END { print count; }'
17476 }
17477
17478 oal_expect_read_count() {
17479         local stats="$1"
17480         local count
17481         local expect="$2"
17482
17483         # Ask ofd_access_log_reader to write stats.
17484         do_facet ost1 killall -USR1 ofd_access_log_reader
17485
17486         # Allow some time for things to happen.
17487         sleep 1
17488
17489         count=$(oal_get_read_count "${stats}")
17490         if ((count == expect)); then
17491                 return 0
17492         fi
17493
17494         error_noexit "bad read count, got ${count}, expected ${expect}"
17495         do_facet ost1 cat "${stats}" >&2
17496         exit 1
17497 }
17498
17499 test_165d() {
17500         local stats="/tmp/${tfile}.stats"
17501         local file="${DIR}/${tdir}/${tfile}"
17502         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17503
17504         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17505                 skip "OFD access log unsupported"
17506
17507         test_mkdir "${DIR}/${tdir}"
17508
17509         setup_165
17510         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17511         sleep 5
17512
17513         lfs setstripe -c 1 -i 0 "${file}"
17514
17515         do_facet ost1 lctl set_param "${param}=rw"
17516         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17517                 error "cannot create '${file}'"
17518         oal_expect_read_count "${stats}" 1
17519
17520         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17521                 error "cannot read '${file}'"
17522         oal_expect_read_count "${stats}" 2
17523
17524         do_facet ost1 lctl set_param "${param}=r"
17525         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17526                 error "cannot create '${file}'"
17527         oal_expect_read_count "${stats}" 2
17528
17529         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17530                 error "cannot read '${file}'"
17531         oal_expect_read_count "${stats}" 3
17532
17533         do_facet ost1 lctl set_param "${param}=w"
17534         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17535                 error "cannot create '${file}'"
17536         oal_expect_read_count "${stats}" 4
17537
17538         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17539                 error "cannot read '${file}'"
17540         oal_expect_read_count "${stats}" 4
17541
17542         do_facet ost1 lctl set_param "${param}=0"
17543         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17544                 error "cannot create '${file}'"
17545         oal_expect_read_count "${stats}" 4
17546
17547         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17548                 error "cannot read '${file}'"
17549         oal_expect_read_count "${stats}" 4
17550
17551         do_facet ost1 killall -TERM ofd_access_log_reader
17552         wait
17553         rc=$?
17554         if ((rc != 0)); then
17555                 error "ofd_access_log_reader exited with rc = '${rc}'"
17556         fi
17557 }
17558 run_test 165d "ofd_access_log mask works"
17559
17560 test_165e() {
17561         local stats="/tmp/${tfile}.stats"
17562         local file0="${DIR}/${tdir}-0/${tfile}"
17563         local file1="${DIR}/${tdir}-1/${tfile}"
17564
17565         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17566                 skip "OFD access log unsupported"
17567
17568         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17569
17570         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17571         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17572
17573         lfs setstripe -c 1 -i 0 "${file0}"
17574         lfs setstripe -c 1 -i 0 "${file1}"
17575
17576         setup_165
17577         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17578         sleep 5
17579
17580         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17581                 error "cannot create '${file0}'"
17582         sync
17583         oal_expect_read_count "${stats}" 0
17584
17585         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17586                 error "cannot create '${file1}'"
17587         sync
17588         oal_expect_read_count "${stats}" 1
17589
17590         do_facet ost1 killall -TERM ofd_access_log_reader
17591         wait
17592         rc=$?
17593         if ((rc != 0)); then
17594                 error "ofd_access_log_reader exited with rc = '${rc}'"
17595         fi
17596 }
17597 run_test 165e "ofd_access_log MDT index filter works"
17598
17599 test_165f() {
17600         local trace="/tmp/${tfile}.trace"
17601         local rc
17602         local count
17603
17604         setup_165
17605         do_facet ost1 timeout 60 ofd_access_log_reader \
17606                 --exit-on-close --debug=- --trace=- > "${trace}" &
17607         sleep 5
17608         stop ost1
17609
17610         wait
17611         rc=$?
17612
17613         if ((rc != 0)); then
17614                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17615                 cat "${trace}"
17616                 exit 1
17617         fi
17618 }
17619 run_test 165f "ofd_access_log_reader --exit-on-close works"
17620
17621 test_169() {
17622         # do directio so as not to populate the page cache
17623         log "creating a 10 Mb file"
17624         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17625                 error "multiop failed while creating a file"
17626         log "starting reads"
17627         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17628         log "truncating the file"
17629         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17630                 error "multiop failed while truncating the file"
17631         log "killing dd"
17632         kill %+ || true # reads might have finished
17633         echo "wait until dd is finished"
17634         wait
17635         log "removing the temporary file"
17636         rm -rf $DIR/$tfile || error "tmp file removal failed"
17637 }
17638 run_test 169 "parallel read and truncate should not deadlock"
17639
17640 test_170() {
17641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17642
17643         $LCTL clear     # bug 18514
17644         $LCTL debug_daemon start $TMP/${tfile}_log_good
17645         touch $DIR/$tfile
17646         $LCTL debug_daemon stop
17647         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17648                 error "sed failed to read log_good"
17649
17650         $LCTL debug_daemon start $TMP/${tfile}_log_good
17651         rm -rf $DIR/$tfile
17652         $LCTL debug_daemon stop
17653
17654         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17655                error "lctl df log_bad failed"
17656
17657         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17658         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17659
17660         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17661         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17662
17663         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17664                 error "bad_line good_line1 good_line2 are empty"
17665
17666         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17667         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17668         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17669
17670         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17671         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17672         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17673
17674         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17675                 error "bad_line_new good_line_new are empty"
17676
17677         local expected_good=$((good_line1 + good_line2*2))
17678
17679         rm -f $TMP/${tfile}*
17680         # LU-231, short malformed line may not be counted into bad lines
17681         if [ $bad_line -ne $bad_line_new ] &&
17682                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17683                 error "expected $bad_line bad lines, but got $bad_line_new"
17684                 return 1
17685         fi
17686
17687         if [ $expected_good -ne $good_line_new ]; then
17688                 error "expected $expected_good good lines, but got $good_line_new"
17689                 return 2
17690         fi
17691         true
17692 }
17693 run_test 170 "test lctl df to handle corrupted log ====================="
17694
17695 test_171() { # bug20592
17696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17697
17698         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17699         $LCTL set_param fail_loc=0x50e
17700         $LCTL set_param fail_val=3000
17701         multiop_bg_pause $DIR/$tfile O_s || true
17702         local MULTIPID=$!
17703         kill -USR1 $MULTIPID
17704         # cause log dump
17705         sleep 3
17706         wait $MULTIPID
17707         if dmesg | grep "recursive fault"; then
17708                 error "caught a recursive fault"
17709         fi
17710         $LCTL set_param fail_loc=0
17711         true
17712 }
17713 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17714
17715 # it would be good to share it with obdfilter-survey/iokit-libecho code
17716 setup_obdecho_osc () {
17717         local rc=0
17718         local ost_nid=$1
17719         local obdfilter_name=$2
17720         echo "Creating new osc for $obdfilter_name on $ost_nid"
17721         # make sure we can find loopback nid
17722         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17723
17724         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17725                            ${obdfilter_name}_osc_UUID || rc=2; }
17726         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17727                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17728         return $rc
17729 }
17730
17731 cleanup_obdecho_osc () {
17732         local obdfilter_name=$1
17733         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17734         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17735         return 0
17736 }
17737
17738 obdecho_test() {
17739         local OBD=$1
17740         local node=$2
17741         local pages=${3:-64}
17742         local rc=0
17743         local id
17744
17745         local count=10
17746         local obd_size=$(get_obd_size $node $OBD)
17747         local page_size=$(get_page_size $node)
17748         if [[ -n "$obd_size" ]]; then
17749                 local new_count=$((obd_size / (pages * page_size / 1024)))
17750                 [[ $new_count -ge $count ]] || count=$new_count
17751         fi
17752
17753         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17754         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17755                            rc=2; }
17756         if [ $rc -eq 0 ]; then
17757             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17758             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17759         fi
17760         echo "New object id is $id"
17761         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17762                            rc=4; }
17763         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17764                            "test_brw $count w v $pages $id" || rc=4; }
17765         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17766                            rc=4; }
17767         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17768                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17769         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17770                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17771         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17772         return $rc
17773 }
17774
17775 test_180a() {
17776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17777
17778         if ! [ -d /sys/fs/lustre/echo_client ] &&
17779            ! module_loaded obdecho; then
17780                 load_module obdecho/obdecho &&
17781                         stack_trap "rmmod obdecho" EXIT ||
17782                         error "unable to load obdecho on client"
17783         fi
17784
17785         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17786         local host=$($LCTL get_param -n osc.$osc.import |
17787                      awk '/current_connection:/ { print $2 }' )
17788         local target=$($LCTL get_param -n osc.$osc.import |
17789                        awk '/target:/ { print $2 }' )
17790         target=${target%_UUID}
17791
17792         if [ -n "$target" ]; then
17793                 setup_obdecho_osc $host $target &&
17794                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17795                         { error "obdecho setup failed with $?"; return; }
17796
17797                 obdecho_test ${target}_osc client ||
17798                         error "obdecho_test failed on ${target}_osc"
17799         else
17800                 $LCTL get_param osc.$osc.import
17801                 error "there is no osc.$osc.import target"
17802         fi
17803 }
17804 run_test 180a "test obdecho on osc"
17805
17806 test_180b() {
17807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17808         remote_ost_nodsh && skip "remote OST with nodsh"
17809
17810         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17811                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17812                 error "failed to load module obdecho"
17813
17814         local target=$(do_facet ost1 $LCTL dl |
17815                        awk '/obdfilter/ { print $4; exit; }')
17816
17817         if [ -n "$target" ]; then
17818                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17819         else
17820                 do_facet ost1 $LCTL dl
17821                 error "there is no obdfilter target on ost1"
17822         fi
17823 }
17824 run_test 180b "test obdecho directly on obdfilter"
17825
17826 test_180c() { # LU-2598
17827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17828         remote_ost_nodsh && skip "remote OST with nodsh"
17829         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17830                 skip "Need MDS version at least 2.4.0"
17831
17832         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17833                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17834                 error "failed to load module obdecho"
17835
17836         local target=$(do_facet ost1 $LCTL dl |
17837                        awk '/obdfilter/ { print $4; exit; }')
17838
17839         if [ -n "$target" ]; then
17840                 local pages=16384 # 64MB bulk I/O RPC size
17841
17842                 obdecho_test "$target" ost1 "$pages" ||
17843                         error "obdecho_test with pages=$pages failed with $?"
17844         else
17845                 do_facet ost1 $LCTL dl
17846                 error "there is no obdfilter target on ost1"
17847         fi
17848 }
17849 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17850
17851 test_181() { # bug 22177
17852         test_mkdir $DIR/$tdir
17853         # create enough files to index the directory
17854         createmany -o $DIR/$tdir/foobar 4000
17855         # print attributes for debug purpose
17856         lsattr -d .
17857         # open dir
17858         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17859         MULTIPID=$!
17860         # remove the files & current working dir
17861         unlinkmany $DIR/$tdir/foobar 4000
17862         rmdir $DIR/$tdir
17863         kill -USR1 $MULTIPID
17864         wait $MULTIPID
17865         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17866         return 0
17867 }
17868 run_test 181 "Test open-unlinked dir ========================"
17869
17870 test_182() {
17871         local fcount=1000
17872         local tcount=10
17873
17874         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17875
17876         $LCTL set_param mdc.*.rpc_stats=clear
17877
17878         for (( i = 0; i < $tcount; i++ )) ; do
17879                 mkdir $DIR/$tdir/$i
17880         done
17881
17882         for (( i = 0; i < $tcount; i++ )) ; do
17883                 createmany -o $DIR/$tdir/$i/f- $fcount &
17884         done
17885         wait
17886
17887         for (( i = 0; i < $tcount; i++ )) ; do
17888                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17889         done
17890         wait
17891
17892         $LCTL get_param mdc.*.rpc_stats
17893
17894         rm -rf $DIR/$tdir
17895 }
17896 run_test 182 "Test parallel modify metadata operations ================"
17897
17898 test_183() { # LU-2275
17899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17900         remote_mds_nodsh && skip "remote MDS with nodsh"
17901         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17902                 skip "Need MDS version at least 2.3.56"
17903
17904         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17905         echo aaa > $DIR/$tdir/$tfile
17906
17907 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17908         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17909
17910         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17911         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17912
17913         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17914
17915         # Flush negative dentry cache
17916         touch $DIR/$tdir/$tfile
17917
17918         # We are not checking for any leaked references here, they'll
17919         # become evident next time we do cleanup with module unload.
17920         rm -rf $DIR/$tdir
17921 }
17922 run_test 183 "No crash or request leak in case of strange dispositions ========"
17923
17924 # test suite 184 is for LU-2016, LU-2017
17925 test_184a() {
17926         check_swap_layouts_support
17927
17928         dir0=$DIR/$tdir/$testnum
17929         test_mkdir -p -c1 $dir0
17930         ref1=/etc/passwd
17931         ref2=/etc/group
17932         file1=$dir0/f1
17933         file2=$dir0/f2
17934         $LFS setstripe -c1 $file1
17935         cp $ref1 $file1
17936         $LFS setstripe -c2 $file2
17937         cp $ref2 $file2
17938         gen1=$($LFS getstripe -g $file1)
17939         gen2=$($LFS getstripe -g $file2)
17940
17941         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17942         gen=$($LFS getstripe -g $file1)
17943         [[ $gen1 != $gen ]] ||
17944                 error "Layout generation on $file1 does not change"
17945         gen=$($LFS getstripe -g $file2)
17946         [[ $gen2 != $gen ]] ||
17947                 error "Layout generation on $file2 does not change"
17948
17949         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17950         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17951
17952         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17953 }
17954 run_test 184a "Basic layout swap"
17955
17956 test_184b() {
17957         check_swap_layouts_support
17958
17959         dir0=$DIR/$tdir/$testnum
17960         mkdir -p $dir0 || error "creating dir $dir0"
17961         file1=$dir0/f1
17962         file2=$dir0/f2
17963         file3=$dir0/f3
17964         dir1=$dir0/d1
17965         dir2=$dir0/d2
17966         mkdir $dir1 $dir2
17967         $LFS setstripe -c1 $file1
17968         $LFS setstripe -c2 $file2
17969         $LFS setstripe -c1 $file3
17970         chown $RUNAS_ID $file3
17971         gen1=$($LFS getstripe -g $file1)
17972         gen2=$($LFS getstripe -g $file2)
17973
17974         $LFS swap_layouts $dir1 $dir2 &&
17975                 error "swap of directories layouts should fail"
17976         $LFS swap_layouts $dir1 $file1 &&
17977                 error "swap of directory and file layouts should fail"
17978         $RUNAS $LFS swap_layouts $file1 $file2 &&
17979                 error "swap of file we cannot write should fail"
17980         $LFS swap_layouts $file1 $file3 &&
17981                 error "swap of file with different owner should fail"
17982         /bin/true # to clear error code
17983 }
17984 run_test 184b "Forbidden layout swap (will generate errors)"
17985
17986 test_184c() {
17987         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17988         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17989         check_swap_layouts_support
17990         check_swap_layout_no_dom $DIR
17991
17992         local dir0=$DIR/$tdir/$testnum
17993         mkdir -p $dir0 || error "creating dir $dir0"
17994
17995         local ref1=$dir0/ref1
17996         local ref2=$dir0/ref2
17997         local file1=$dir0/file1
17998         local file2=$dir0/file2
17999         # create a file large enough for the concurrent test
18000         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18001         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18002         echo "ref file size: ref1($(stat -c %s $ref1))," \
18003              "ref2($(stat -c %s $ref2))"
18004
18005         cp $ref2 $file2
18006         dd if=$ref1 of=$file1 bs=16k &
18007         local DD_PID=$!
18008
18009         # Make sure dd starts to copy file, but wait at most 5 seconds
18010         local loops=0
18011         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18012
18013         $LFS swap_layouts $file1 $file2
18014         local rc=$?
18015         wait $DD_PID
18016         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18017         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18018
18019         # how many bytes copied before swapping layout
18020         local copied=$(stat -c %s $file2)
18021         local remaining=$(stat -c %s $ref1)
18022         remaining=$((remaining - copied))
18023         echo "Copied $copied bytes before swapping layout..."
18024
18025         cmp -n $copied $file1 $ref2 | grep differ &&
18026                 error "Content mismatch [0, $copied) of ref2 and file1"
18027         cmp -n $copied $file2 $ref1 ||
18028                 error "Content mismatch [0, $copied) of ref1 and file2"
18029         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18030                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18031
18032         # clean up
18033         rm -f $ref1 $ref2 $file1 $file2
18034 }
18035 run_test 184c "Concurrent write and layout swap"
18036
18037 test_184d() {
18038         check_swap_layouts_support
18039         check_swap_layout_no_dom $DIR
18040         [ -z "$(which getfattr 2>/dev/null)" ] &&
18041                 skip_env "no getfattr command"
18042
18043         local file1=$DIR/$tdir/$tfile-1
18044         local file2=$DIR/$tdir/$tfile-2
18045         local file3=$DIR/$tdir/$tfile-3
18046         local lovea1
18047         local lovea2
18048
18049         mkdir -p $DIR/$tdir
18050         touch $file1 || error "create $file1 failed"
18051         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18052                 error "create $file2 failed"
18053         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18054                 error "create $file3 failed"
18055         lovea1=$(get_layout_param $file1)
18056
18057         $LFS swap_layouts $file2 $file3 ||
18058                 error "swap $file2 $file3 layouts failed"
18059         $LFS swap_layouts $file1 $file2 ||
18060                 error "swap $file1 $file2 layouts failed"
18061
18062         lovea2=$(get_layout_param $file2)
18063         echo "$lovea1"
18064         echo "$lovea2"
18065         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18066
18067         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18068         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18069 }
18070 run_test 184d "allow stripeless layouts swap"
18071
18072 test_184e() {
18073         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18074                 skip "Need MDS version at least 2.6.94"
18075         check_swap_layouts_support
18076         check_swap_layout_no_dom $DIR
18077         [ -z "$(which getfattr 2>/dev/null)" ] &&
18078                 skip_env "no getfattr command"
18079
18080         local file1=$DIR/$tdir/$tfile-1
18081         local file2=$DIR/$tdir/$tfile-2
18082         local file3=$DIR/$tdir/$tfile-3
18083         local lovea
18084
18085         mkdir -p $DIR/$tdir
18086         touch $file1 || error "create $file1 failed"
18087         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18088                 error "create $file2 failed"
18089         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18090                 error "create $file3 failed"
18091
18092         $LFS swap_layouts $file1 $file2 ||
18093                 error "swap $file1 $file2 layouts failed"
18094
18095         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18096         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18097
18098         echo 123 > $file1 || error "Should be able to write into $file1"
18099
18100         $LFS swap_layouts $file1 $file3 ||
18101                 error "swap $file1 $file3 layouts failed"
18102
18103         echo 123 > $file1 || error "Should be able to write into $file1"
18104
18105         rm -rf $file1 $file2 $file3
18106 }
18107 run_test 184e "Recreate layout after stripeless layout swaps"
18108
18109 test_184f() {
18110         # Create a file with name longer than sizeof(struct stat) ==
18111         # 144 to see if we can get chars from the file name to appear
18112         # in the returned striping. Note that 'f' == 0x66.
18113         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18114
18115         mkdir -p $DIR/$tdir
18116         mcreate $DIR/$tdir/$file
18117         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18118                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18119         fi
18120 }
18121 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18122
18123 test_185() { # LU-2441
18124         # LU-3553 - no volatile file support in old servers
18125         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18126                 skip "Need MDS version at least 2.3.60"
18127
18128         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18129         touch $DIR/$tdir/spoo
18130         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18131         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18132                 error "cannot create/write a volatile file"
18133         [ "$FILESET" == "" ] &&
18134         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18135                 error "FID is still valid after close"
18136
18137         multiop_bg_pause $DIR/$tdir vVw4096_c
18138         local multi_pid=$!
18139
18140         local OLD_IFS=$IFS
18141         IFS=":"
18142         local fidv=($fid)
18143         IFS=$OLD_IFS
18144         # assume that the next FID for this client is sequential, since stdout
18145         # is unfortunately eaten by multiop_bg_pause
18146         local n=$((${fidv[1]} + 1))
18147         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18148         if [ "$FILESET" == "" ]; then
18149                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18150                         error "FID is missing before close"
18151         fi
18152         kill -USR1 $multi_pid
18153         # 1 second delay, so if mtime change we will see it
18154         sleep 1
18155         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18156         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18157 }
18158 run_test 185 "Volatile file support"
18159
18160 function create_check_volatile() {
18161         local idx=$1
18162         local tgt
18163
18164         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18165         local PID=$!
18166         sleep 1
18167         local FID=$(cat /tmp/${tfile}.fid)
18168         [ "$FID" == "" ] && error "can't get FID for volatile"
18169         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18170         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18171         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18172         kill -USR1 $PID
18173         wait
18174         sleep 1
18175         cancel_lru_locks mdc # flush opencache
18176         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18177         return 0
18178 }
18179
18180 test_185a(){
18181         # LU-12516 - volatile creation via .lustre
18182         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18183                 skip "Need MDS version at least 2.3.55"
18184
18185         create_check_volatile 0
18186         [ $MDSCOUNT -lt 2 ] && return 0
18187
18188         # DNE case
18189         create_check_volatile 1
18190
18191         return 0
18192 }
18193 run_test 185a "Volatile file creation in .lustre/fid/"
18194
18195 test_187a() {
18196         remote_mds_nodsh && skip "remote MDS with nodsh"
18197         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18198                 skip "Need MDS version at least 2.3.0"
18199
18200         local dir0=$DIR/$tdir/$testnum
18201         mkdir -p $dir0 || error "creating dir $dir0"
18202
18203         local file=$dir0/file1
18204         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18205         local dv1=$($LFS data_version $file)
18206         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18207         local dv2=$($LFS data_version $file)
18208         [[ $dv1 != $dv2 ]] ||
18209                 error "data version did not change on write $dv1 == $dv2"
18210
18211         # clean up
18212         rm -f $file1
18213 }
18214 run_test 187a "Test data version change"
18215
18216 test_187b() {
18217         remote_mds_nodsh && skip "remote MDS with nodsh"
18218         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18219                 skip "Need MDS version at least 2.3.0"
18220
18221         local dir0=$DIR/$tdir/$testnum
18222         mkdir -p $dir0 || error "creating dir $dir0"
18223
18224         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18225         [[ ${DV[0]} != ${DV[1]} ]] ||
18226                 error "data version did not change on write"\
18227                       " ${DV[0]} == ${DV[1]}"
18228
18229         # clean up
18230         rm -f $file1
18231 }
18232 run_test 187b "Test data version change on volatile file"
18233
18234 test_200() {
18235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18236         remote_mgs_nodsh && skip "remote MGS with nodsh"
18237         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18238
18239         local POOL=${POOL:-cea1}
18240         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18241         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18242         # Pool OST targets
18243         local first_ost=0
18244         local last_ost=$(($OSTCOUNT - 1))
18245         local ost_step=2
18246         local ost_list=$(seq $first_ost $ost_step $last_ost)
18247         local ost_range="$first_ost $last_ost $ost_step"
18248         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18249         local file_dir=$POOL_ROOT/file_tst
18250         local subdir=$test_path/subdir
18251         local rc=0
18252
18253         while : ; do
18254                 # former test_200a test_200b
18255                 pool_add $POOL                          || { rc=$? ; break; }
18256                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18257                 # former test_200c test_200d
18258                 mkdir -p $test_path
18259                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18260                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18261                 mkdir -p $subdir
18262                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18263                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18264                                                         || { rc=$? ; break; }
18265                 # former test_200e test_200f
18266                 local files=$((OSTCOUNT*3))
18267                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18268                                                         || { rc=$? ; break; }
18269                 pool_create_files $POOL $file_dir $files "$ost_list" \
18270                                                         || { rc=$? ; break; }
18271                 # former test_200g test_200h
18272                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18273                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18274
18275                 # former test_201a test_201b test_201c
18276                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18277
18278                 local f=$test_path/$tfile
18279                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18280                 pool_remove $POOL $f                    || { rc=$? ; break; }
18281                 break
18282         done
18283
18284         destroy_test_pools
18285
18286         return $rc
18287 }
18288 run_test 200 "OST pools"
18289
18290 # usage: default_attr <count | size | offset>
18291 default_attr() {
18292         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18293 }
18294
18295 # usage: check_default_stripe_attr
18296 check_default_stripe_attr() {
18297         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18298         case $1 in
18299         --stripe-count|-c)
18300                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18301         --stripe-size|-S)
18302                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18303         --stripe-index|-i)
18304                 EXPECTED=-1;;
18305         *)
18306                 error "unknown getstripe attr '$1'"
18307         esac
18308
18309         [ $ACTUAL == $EXPECTED ] ||
18310                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18311 }
18312
18313 test_204a() {
18314         test_mkdir $DIR/$tdir
18315         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18316
18317         check_default_stripe_attr --stripe-count
18318         check_default_stripe_attr --stripe-size
18319         check_default_stripe_attr --stripe-index
18320 }
18321 run_test 204a "Print default stripe attributes"
18322
18323 test_204b() {
18324         test_mkdir $DIR/$tdir
18325         $LFS setstripe --stripe-count 1 $DIR/$tdir
18326
18327         check_default_stripe_attr --stripe-size
18328         check_default_stripe_attr --stripe-index
18329 }
18330 run_test 204b "Print default stripe size and offset"
18331
18332 test_204c() {
18333         test_mkdir $DIR/$tdir
18334         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18335
18336         check_default_stripe_attr --stripe-count
18337         check_default_stripe_attr --stripe-index
18338 }
18339 run_test 204c "Print default stripe count and offset"
18340
18341 test_204d() {
18342         test_mkdir $DIR/$tdir
18343         $LFS setstripe --stripe-index 0 $DIR/$tdir
18344
18345         check_default_stripe_attr --stripe-count
18346         check_default_stripe_attr --stripe-size
18347 }
18348 run_test 204d "Print default stripe count and size"
18349
18350 test_204e() {
18351         test_mkdir $DIR/$tdir
18352         $LFS setstripe -d $DIR/$tdir
18353
18354         check_default_stripe_attr --stripe-count --raw
18355         check_default_stripe_attr --stripe-size --raw
18356         check_default_stripe_attr --stripe-index --raw
18357 }
18358 run_test 204e "Print raw stripe attributes"
18359
18360 test_204f() {
18361         test_mkdir $DIR/$tdir
18362         $LFS setstripe --stripe-count 1 $DIR/$tdir
18363
18364         check_default_stripe_attr --stripe-size --raw
18365         check_default_stripe_attr --stripe-index --raw
18366 }
18367 run_test 204f "Print raw stripe size and offset"
18368
18369 test_204g() {
18370         test_mkdir $DIR/$tdir
18371         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18372
18373         check_default_stripe_attr --stripe-count --raw
18374         check_default_stripe_attr --stripe-index --raw
18375 }
18376 run_test 204g "Print raw stripe count and offset"
18377
18378 test_204h() {
18379         test_mkdir $DIR/$tdir
18380         $LFS setstripe --stripe-index 0 $DIR/$tdir
18381
18382         check_default_stripe_attr --stripe-count --raw
18383         check_default_stripe_attr --stripe-size --raw
18384 }
18385 run_test 204h "Print raw stripe count and size"
18386
18387 # Figure out which job scheduler is being used, if any,
18388 # or use a fake one
18389 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18390         JOBENV=SLURM_JOB_ID
18391 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18392         JOBENV=LSB_JOBID
18393 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18394         JOBENV=PBS_JOBID
18395 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18396         JOBENV=LOADL_STEP_ID
18397 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18398         JOBENV=JOB_ID
18399 else
18400         $LCTL list_param jobid_name > /dev/null 2>&1
18401         if [ $? -eq 0 ]; then
18402                 JOBENV=nodelocal
18403         else
18404                 JOBENV=FAKE_JOBID
18405         fi
18406 fi
18407 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18408
18409 verify_jobstats() {
18410         local cmd=($1)
18411         shift
18412         local facets="$@"
18413
18414 # we don't really need to clear the stats for this test to work, since each
18415 # command has a unique jobid, but it makes debugging easier if needed.
18416 #       for facet in $facets; do
18417 #               local dev=$(convert_facet2label $facet)
18418 #               # clear old jobstats
18419 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18420 #       done
18421
18422         # use a new JobID for each test, or we might see an old one
18423         [ "$JOBENV" = "FAKE_JOBID" ] &&
18424                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18425
18426         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18427
18428         [ "$JOBENV" = "nodelocal" ] && {
18429                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18430                 $LCTL set_param jobid_name=$FAKE_JOBID
18431                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18432         }
18433
18434         log "Test: ${cmd[*]}"
18435         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18436
18437         if [ $JOBENV = "FAKE_JOBID" ]; then
18438                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18439         else
18440                 ${cmd[*]}
18441         fi
18442
18443         # all files are created on OST0000
18444         for facet in $facets; do
18445                 local stats="*.$(convert_facet2label $facet).job_stats"
18446
18447                 # strip out libtool wrappers for in-tree executables
18448                 if (( $(do_facet $facet lctl get_param $stats |
18449                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18450                         do_facet $facet lctl get_param $stats
18451                         error "No jobstats for $JOBVAL found on $facet::$stats"
18452                 fi
18453         done
18454 }
18455
18456 jobstats_set() {
18457         local new_jobenv=$1
18458
18459         set_persistent_param_and_check client "jobid_var" \
18460                 "$FSNAME.sys.jobid_var" $new_jobenv
18461 }
18462
18463 test_205a() { # Job stats
18464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18465         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18466                 skip "Need MDS version with at least 2.7.1"
18467         remote_mgs_nodsh && skip "remote MGS with nodsh"
18468         remote_mds_nodsh && skip "remote MDS with nodsh"
18469         remote_ost_nodsh && skip "remote OST with nodsh"
18470         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18471                 skip "Server doesn't support jobstats"
18472         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18473
18474         local old_jobenv=$($LCTL get_param -n jobid_var)
18475         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18476
18477         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18478                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18479         else
18480                 stack_trap "do_facet mgs $PERM_CMD \
18481                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18482         fi
18483         changelog_register
18484
18485         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18486                                 mdt.*.job_cleanup_interval | head -n 1)
18487         local new_interval=5
18488         do_facet $SINGLEMDS \
18489                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18490         stack_trap "do_facet $SINGLEMDS \
18491                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18492         local start=$SECONDS
18493
18494         local cmd
18495         # mkdir
18496         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18497         verify_jobstats "$cmd" "$SINGLEMDS"
18498         # rmdir
18499         cmd="rmdir $DIR/$tdir"
18500         verify_jobstats "$cmd" "$SINGLEMDS"
18501         # mkdir on secondary MDT
18502         if [ $MDSCOUNT -gt 1 ]; then
18503                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18504                 verify_jobstats "$cmd" "mds2"
18505         fi
18506         # mknod
18507         cmd="mknod $DIR/$tfile c 1 3"
18508         verify_jobstats "$cmd" "$SINGLEMDS"
18509         # unlink
18510         cmd="rm -f $DIR/$tfile"
18511         verify_jobstats "$cmd" "$SINGLEMDS"
18512         # create all files on OST0000 so verify_jobstats can find OST stats
18513         # open & close
18514         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18515         verify_jobstats "$cmd" "$SINGLEMDS"
18516         # setattr
18517         cmd="touch $DIR/$tfile"
18518         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18519         # write
18520         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18521         verify_jobstats "$cmd" "ost1"
18522         # read
18523         cancel_lru_locks osc
18524         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18525         verify_jobstats "$cmd" "ost1"
18526         # truncate
18527         cmd="$TRUNCATE $DIR/$tfile 0"
18528         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18529         # rename
18530         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18531         verify_jobstats "$cmd" "$SINGLEMDS"
18532         # jobstats expiry - sleep until old stats should be expired
18533         local left=$((new_interval + 5 - (SECONDS - start)))
18534         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18535                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18536                         "0" $left
18537         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18538         verify_jobstats "$cmd" "$SINGLEMDS"
18539         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18540             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18541
18542         # Ensure that jobid are present in changelog (if supported by MDS)
18543         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18544                 changelog_dump | tail -10
18545                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18546                 [ $jobids -eq 9 ] ||
18547                         error "Wrong changelog jobid count $jobids != 9"
18548
18549                 # LU-5862
18550                 JOBENV="disable"
18551                 jobstats_set $JOBENV
18552                 touch $DIR/$tfile
18553                 changelog_dump | grep $tfile
18554                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18555                 [ $jobids -eq 0 ] ||
18556                         error "Unexpected jobids when jobid_var=$JOBENV"
18557         fi
18558
18559         # test '%j' access to environment variable - if supported
18560         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18561                 JOBENV="JOBCOMPLEX"
18562                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18563
18564                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18565         fi
18566
18567         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18568                 JOBENV="JOBCOMPLEX"
18569                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18570
18571                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18572         fi
18573
18574         # test '%j' access to per-session jobid - if supported
18575         if lctl list_param jobid_this_session > /dev/null 2>&1
18576         then
18577                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18578                 lctl set_param jobid_this_session=$USER
18579
18580                 JOBENV="JOBCOMPLEX"
18581                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18582
18583                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18584         fi
18585 }
18586 run_test 205a "Verify job stats"
18587
18588 # LU-13117, LU-13597
18589 test_205b() {
18590         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18591                 skip "Need MDS version at least 2.13.54.91"
18592
18593         job_stats="mdt.*.job_stats"
18594         $LCTL set_param $job_stats=clear
18595         # Setting jobid_var to USER might not be supported
18596         $LCTL set_param jobid_var=USER || true
18597         $LCTL set_param jobid_name="%e.%u"
18598         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18599         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18600                 grep "job_id:.*foolish" &&
18601                         error "Unexpected jobid found"
18602         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18603                 grep "open:.*min.*max.*sum" ||
18604                         error "wrong job_stats format found"
18605 }
18606 run_test 205b "Verify job stats jobid and output format"
18607
18608 # LU-13733
18609 test_205c() {
18610         $LCTL set_param llite.*.stats=0
18611         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18612         $LCTL get_param llite.*.stats
18613         $LCTL get_param llite.*.stats | grep \
18614                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18615                         error "wrong client stats format found"
18616 }
18617 run_test 205c "Verify client stats format"
18618
18619 # LU-1480, LU-1773 and LU-1657
18620 test_206() {
18621         mkdir -p $DIR/$tdir
18622         $LFS setstripe -c -1 $DIR/$tdir
18623 #define OBD_FAIL_LOV_INIT 0x1403
18624         $LCTL set_param fail_loc=0xa0001403
18625         $LCTL set_param fail_val=1
18626         touch $DIR/$tdir/$tfile || true
18627 }
18628 run_test 206 "fail lov_init_raid0() doesn't lbug"
18629
18630 test_207a() {
18631         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18632         local fsz=`stat -c %s $DIR/$tfile`
18633         cancel_lru_locks mdc
18634
18635         # do not return layout in getattr intent
18636 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18637         $LCTL set_param fail_loc=0x170
18638         local sz=`stat -c %s $DIR/$tfile`
18639
18640         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18641
18642         rm -rf $DIR/$tfile
18643 }
18644 run_test 207a "can refresh layout at glimpse"
18645
18646 test_207b() {
18647         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18648         local cksum=`md5sum $DIR/$tfile`
18649         local fsz=`stat -c %s $DIR/$tfile`
18650         cancel_lru_locks mdc
18651         cancel_lru_locks osc
18652
18653         # do not return layout in getattr intent
18654 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18655         $LCTL set_param fail_loc=0x171
18656
18657         # it will refresh layout after the file is opened but before read issues
18658         echo checksum is "$cksum"
18659         echo "$cksum" |md5sum -c --quiet || error "file differs"
18660
18661         rm -rf $DIR/$tfile
18662 }
18663 run_test 207b "can refresh layout at open"
18664
18665 test_208() {
18666         # FIXME: in this test suite, only RD lease is used. This is okay
18667         # for now as only exclusive open is supported. After generic lease
18668         # is done, this test suite should be revised. - Jinshan
18669
18670         remote_mds_nodsh && skip "remote MDS with nodsh"
18671         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18672                 skip "Need MDS version at least 2.4.52"
18673
18674         echo "==== test 1: verify get lease work"
18675         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18676
18677         echo "==== test 2: verify lease can be broken by upcoming open"
18678         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18679         local PID=$!
18680         sleep 2
18681
18682         $MULTIOP $DIR/$tfile oO_RDWR:c
18683         kill -USR1 $PID && wait $PID || error "break lease error"
18684
18685         echo "==== test 3: verify lease can't be granted if an open already exists"
18686         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18687         local PID=$!
18688         sleep 2
18689
18690         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18691         kill -USR1 $PID && wait $PID || error "open file error"
18692
18693         echo "==== test 4: lease can sustain over recovery"
18694         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18695         PID=$!
18696         sleep 2
18697
18698         fail mds1
18699
18700         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18701
18702         echo "==== test 5: lease broken can't be regained by replay"
18703         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18704         PID=$!
18705         sleep 2
18706
18707         # open file to break lease and then recovery
18708         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18709         fail mds1
18710
18711         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18712
18713         rm -f $DIR/$tfile
18714 }
18715 run_test 208 "Exclusive open"
18716
18717 test_209() {
18718         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18719                 skip_env "must have disp_stripe"
18720
18721         touch $DIR/$tfile
18722         sync; sleep 5; sync;
18723
18724         echo 3 > /proc/sys/vm/drop_caches
18725         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18726                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18727         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18728
18729         # open/close 500 times
18730         for i in $(seq 500); do
18731                 cat $DIR/$tfile
18732         done
18733
18734         echo 3 > /proc/sys/vm/drop_caches
18735         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18736                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18737         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18738
18739         echo "before: $req_before, after: $req_after"
18740         [ $((req_after - req_before)) -ge 300 ] &&
18741                 error "open/close requests are not freed"
18742         return 0
18743 }
18744 run_test 209 "read-only open/close requests should be freed promptly"
18745
18746 test_210() {
18747         local pid
18748
18749         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18750         pid=$!
18751         sleep 1
18752
18753         $LFS getstripe $DIR/$tfile
18754         kill -USR1 $pid
18755         wait $pid || error "multiop failed"
18756
18757         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18758         pid=$!
18759         sleep 1
18760
18761         $LFS getstripe $DIR/$tfile
18762         kill -USR1 $pid
18763         wait $pid || error "multiop failed"
18764 }
18765 run_test 210 "lfs getstripe does not break leases"
18766
18767 test_212() {
18768         size=`date +%s`
18769         size=$((size % 8192 + 1))
18770         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18771         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18772         rm -f $DIR/f212 $DIR/f212.xyz
18773 }
18774 run_test 212 "Sendfile test ============================================"
18775
18776 test_213() {
18777         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18778         cancel_lru_locks osc
18779         lctl set_param fail_loc=0x8000040f
18780         # generate a read lock
18781         cat $DIR/$tfile > /dev/null
18782         # write to the file, it will try to cancel the above read lock.
18783         cat /etc/hosts >> $DIR/$tfile
18784 }
18785 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18786
18787 test_214() { # for bug 20133
18788         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18789         for (( i=0; i < 340; i++ )) ; do
18790                 touch $DIR/$tdir/d214c/a$i
18791         done
18792
18793         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18794         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18795         ls $DIR/d214c || error "ls $DIR/d214c failed"
18796         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18797         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18798 }
18799 run_test 214 "hash-indexed directory test - bug 20133"
18800
18801 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18802 create_lnet_proc_files() {
18803         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18804 }
18805
18806 # counterpart of create_lnet_proc_files
18807 remove_lnet_proc_files() {
18808         rm -f $TMP/lnet_$1.sys
18809 }
18810
18811 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18812 # 3rd arg as regexp for body
18813 check_lnet_proc_stats() {
18814         local l=$(cat "$TMP/lnet_$1" |wc -l)
18815         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18816
18817         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18818 }
18819
18820 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18821 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18822 # optional and can be regexp for 2nd line (lnet.routes case)
18823 check_lnet_proc_entry() {
18824         local blp=2          # blp stands for 'position of 1st line of body'
18825         [ -z "$5" ] || blp=3 # lnet.routes case
18826
18827         local l=$(cat "$TMP/lnet_$1" |wc -l)
18828         # subtracting one from $blp because the body can be empty
18829         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18830
18831         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18832                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18833
18834         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18835                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18836
18837         # bail out if any unexpected line happened
18838         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18839         [ "$?" != 0 ] || error "$2 misformatted"
18840 }
18841
18842 test_215() { # for bugs 18102, 21079, 21517
18843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18844
18845         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18846         local P='[1-9][0-9]*'           # positive numeric
18847         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18848         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18849         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18850         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18851
18852         local L1 # regexp for 1st line
18853         local L2 # regexp for 2nd line (optional)
18854         local BR # regexp for the rest (body)
18855
18856         # lnet.stats should look as 11 space-separated non-negative numerics
18857         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18858         create_lnet_proc_files "stats"
18859         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18860         remove_lnet_proc_files "stats"
18861
18862         # lnet.routes should look like this:
18863         # Routing disabled/enabled
18864         # net hops priority state router
18865         # where net is a string like tcp0, hops > 0, priority >= 0,
18866         # state is up/down,
18867         # router is a string like 192.168.1.1@tcp2
18868         L1="^Routing (disabled|enabled)$"
18869         L2="^net +hops +priority +state +router$"
18870         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18871         create_lnet_proc_files "routes"
18872         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18873         remove_lnet_proc_files "routes"
18874
18875         # lnet.routers should look like this:
18876         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18877         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18878         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18879         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18880         L1="^ref +rtr_ref +alive +router$"
18881         BR="^$P +$P +(up|down) +$NID$"
18882         create_lnet_proc_files "routers"
18883         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18884         remove_lnet_proc_files "routers"
18885
18886         # lnet.peers should look like this:
18887         # nid refs state last max rtr min tx min queue
18888         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18889         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18890         # numeric (0 or >0 or <0), queue >= 0.
18891         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18892         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18893         create_lnet_proc_files "peers"
18894         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18895         remove_lnet_proc_files "peers"
18896
18897         # lnet.buffers  should look like this:
18898         # pages count credits min
18899         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18900         L1="^pages +count +credits +min$"
18901         BR="^ +$N +$N +$I +$I$"
18902         create_lnet_proc_files "buffers"
18903         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18904         remove_lnet_proc_files "buffers"
18905
18906         # lnet.nis should look like this:
18907         # nid status alive refs peer rtr max tx min
18908         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18909         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18910         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18911         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18912         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18913         create_lnet_proc_files "nis"
18914         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18915         remove_lnet_proc_files "nis"
18916
18917         # can we successfully write to lnet.stats?
18918         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18919 }
18920 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18921
18922 test_216() { # bug 20317
18923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18924         remote_ost_nodsh && skip "remote OST with nodsh"
18925
18926         local node
18927         local facets=$(get_facets OST)
18928         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18929
18930         save_lustre_params client "osc.*.contention_seconds" > $p
18931         save_lustre_params $facets \
18932                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18933         save_lustre_params $facets \
18934                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18935         save_lustre_params $facets \
18936                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18937         clear_stats osc.*.osc_stats
18938
18939         # agressive lockless i/o settings
18940         do_nodes $(comma_list $(osts_nodes)) \
18941                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18942                         ldlm.namespaces.filter-*.contended_locks=0 \
18943                         ldlm.namespaces.filter-*.contention_seconds=60"
18944         lctl set_param -n osc.*.contention_seconds=60
18945
18946         $DIRECTIO write $DIR/$tfile 0 10 4096
18947         $CHECKSTAT -s 40960 $DIR/$tfile
18948
18949         # disable lockless i/o
18950         do_nodes $(comma_list $(osts_nodes)) \
18951                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18952                         ldlm.namespaces.filter-*.contended_locks=32 \
18953                         ldlm.namespaces.filter-*.contention_seconds=0"
18954         lctl set_param -n osc.*.contention_seconds=0
18955         clear_stats osc.*.osc_stats
18956
18957         dd if=/dev/zero of=$DIR/$tfile count=0
18958         $CHECKSTAT -s 0 $DIR/$tfile
18959
18960         restore_lustre_params <$p
18961         rm -f $p
18962         rm $DIR/$tfile
18963 }
18964 run_test 216 "check lockless direct write updates file size and kms correctly"
18965
18966 test_217() { # bug 22430
18967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18968
18969         local node
18970         local nid
18971
18972         for node in $(nodes_list); do
18973                 nid=$(host_nids_address $node $NETTYPE)
18974                 if [[ $nid = *-* ]] ; then
18975                         echo "lctl ping $(h2nettype $nid)"
18976                         lctl ping $(h2nettype $nid)
18977                 else
18978                         echo "skipping $node (no hyphen detected)"
18979                 fi
18980         done
18981 }
18982 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18983
18984 test_218() {
18985        # do directio so as not to populate the page cache
18986        log "creating a 10 Mb file"
18987        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18988        log "starting reads"
18989        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18990        log "truncating the file"
18991        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18992        log "killing dd"
18993        kill %+ || true # reads might have finished
18994        echo "wait until dd is finished"
18995        wait
18996        log "removing the temporary file"
18997        rm -rf $DIR/$tfile || error "tmp file removal failed"
18998 }
18999 run_test 218 "parallel read and truncate should not deadlock"
19000
19001 test_219() {
19002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19003
19004         # write one partial page
19005         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19006         # set no grant so vvp_io_commit_write will do sync write
19007         $LCTL set_param fail_loc=0x411
19008         # write a full page at the end of file
19009         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19010
19011         $LCTL set_param fail_loc=0
19012         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19013         $LCTL set_param fail_loc=0x411
19014         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19015
19016         # LU-4201
19017         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19018         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19019 }
19020 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19021
19022 test_220() { #LU-325
19023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19024         remote_ost_nodsh && skip "remote OST with nodsh"
19025         remote_mds_nodsh && skip "remote MDS with nodsh"
19026         remote_mgs_nodsh && skip "remote MGS with nodsh"
19027
19028         local OSTIDX=0
19029
19030         # create on MDT0000 so the last_id and next_id are correct
19031         mkdir_on_mdt0 $DIR/$tdir
19032         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19033         OST=${OST%_UUID}
19034
19035         # on the mdt's osc
19036         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19037         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19038                         osp.$mdtosc_proc1.prealloc_last_id)
19039         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19040                         osp.$mdtosc_proc1.prealloc_next_id)
19041
19042         $LFS df -i
19043
19044         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19045         #define OBD_FAIL_OST_ENOINO              0x229
19046         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19047         create_pool $FSNAME.$TESTNAME || return 1
19048         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19049
19050         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19051
19052         MDSOBJS=$((last_id - next_id))
19053         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19054
19055         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19056         echo "OST still has $count kbytes free"
19057
19058         echo "create $MDSOBJS files @next_id..."
19059         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19060
19061         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19062                         osp.$mdtosc_proc1.prealloc_last_id)
19063         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19064                         osp.$mdtosc_proc1.prealloc_next_id)
19065
19066         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19067         $LFS df -i
19068
19069         echo "cleanup..."
19070
19071         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19072         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19073
19074         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19075                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19076         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19077                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19078         echo "unlink $MDSOBJS files @$next_id..."
19079         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19080 }
19081 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19082
19083 test_221() {
19084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19085
19086         dd if=`which date` of=$MOUNT/date oflag=sync
19087         chmod +x $MOUNT/date
19088
19089         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19090         $LCTL set_param fail_loc=0x80001401
19091
19092         $MOUNT/date > /dev/null
19093         rm -f $MOUNT/date
19094 }
19095 run_test 221 "make sure fault and truncate race to not cause OOM"
19096
19097 test_222a () {
19098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19099
19100         rm -rf $DIR/$tdir
19101         test_mkdir $DIR/$tdir
19102         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19103         createmany -o $DIR/$tdir/$tfile 10
19104         cancel_lru_locks mdc
19105         cancel_lru_locks osc
19106         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19107         $LCTL set_param fail_loc=0x31a
19108         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19109         $LCTL set_param fail_loc=0
19110         rm -r $DIR/$tdir
19111 }
19112 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19113
19114 test_222b () {
19115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19116
19117         rm -rf $DIR/$tdir
19118         test_mkdir $DIR/$tdir
19119         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19120         createmany -o $DIR/$tdir/$tfile 10
19121         cancel_lru_locks mdc
19122         cancel_lru_locks osc
19123         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19124         $LCTL set_param fail_loc=0x31a
19125         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19126         $LCTL set_param fail_loc=0
19127 }
19128 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19129
19130 test_223 () {
19131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19132
19133         rm -rf $DIR/$tdir
19134         test_mkdir $DIR/$tdir
19135         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19136         createmany -o $DIR/$tdir/$tfile 10
19137         cancel_lru_locks mdc
19138         cancel_lru_locks osc
19139         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19140         $LCTL set_param fail_loc=0x31b
19141         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19142         $LCTL set_param fail_loc=0
19143         rm -r $DIR/$tdir
19144 }
19145 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19146
19147 test_224a() { # LU-1039, MRP-303
19148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19149         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19150         $LCTL set_param fail_loc=0x508
19151         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19152         $LCTL set_param fail_loc=0
19153         df $DIR
19154 }
19155 run_test 224a "Don't panic on bulk IO failure"
19156
19157 test_224bd_sub() { # LU-1039, MRP-303
19158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19159         local timeout=$1
19160
19161         shift
19162         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19163
19164         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19165
19166         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19167         cancel_lru_locks osc
19168         set_checksums 0
19169         stack_trap "set_checksums $ORIG_CSUM" EXIT
19170         local at_max_saved=0
19171
19172         # adaptive timeouts may prevent seeing the issue
19173         if at_is_enabled; then
19174                 at_max_saved=$(at_max_get mds)
19175                 at_max_set 0 mds client
19176                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19177         fi
19178
19179         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19180         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19181         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19182
19183         do_facet ost1 $LCTL set_param fail_loc=0
19184         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19185         df $DIR
19186 }
19187
19188 test_224b() {
19189         test_224bd_sub 3 error "dd failed"
19190 }
19191 run_test 224b "Don't panic on bulk IO failure"
19192
19193 test_224c() { # LU-6441
19194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19195         remote_mds_nodsh && skip "remote MDS with nodsh"
19196
19197         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19198         save_writethrough $p
19199         set_cache writethrough on
19200
19201         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19202         local at_max=$($LCTL get_param -n at_max)
19203         local timeout=$($LCTL get_param -n timeout)
19204         local test_at="at_max"
19205         local param_at="$FSNAME.sys.at_max"
19206         local test_timeout="timeout"
19207         local param_timeout="$FSNAME.sys.timeout"
19208
19209         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19210
19211         set_persistent_param_and_check client "$test_at" "$param_at" 0
19212         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19213
19214         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19215         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19216         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19217         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19218         sync
19219         do_facet ost1 "$LCTL set_param fail_loc=0"
19220
19221         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19222         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19223                 $timeout
19224
19225         $LCTL set_param -n $pages_per_rpc
19226         restore_lustre_params < $p
19227         rm -f $p
19228 }
19229 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19230
19231 test_224d() { # LU-11169
19232         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19233 }
19234 run_test 224d "Don't corrupt data on bulk IO timeout"
19235
19236 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19237 test_225a () {
19238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19239         if [ -z ${MDSSURVEY} ]; then
19240                 skip_env "mds-survey not found"
19241         fi
19242         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19243                 skip "Need MDS version at least 2.2.51"
19244
19245         local mds=$(facet_host $SINGLEMDS)
19246         local target=$(do_nodes $mds 'lctl dl' |
19247                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19248
19249         local cmd1="file_count=1000 thrhi=4"
19250         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19251         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19252         local cmd="$cmd1 $cmd2 $cmd3"
19253
19254         rm -f ${TMP}/mds_survey*
19255         echo + $cmd
19256         eval $cmd || error "mds-survey with zero-stripe failed"
19257         cat ${TMP}/mds_survey*
19258         rm -f ${TMP}/mds_survey*
19259 }
19260 run_test 225a "Metadata survey sanity with zero-stripe"
19261
19262 test_225b () {
19263         if [ -z ${MDSSURVEY} ]; then
19264                 skip_env "mds-survey not found"
19265         fi
19266         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19267                 skip "Need MDS version at least 2.2.51"
19268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19269         remote_mds_nodsh && skip "remote MDS with nodsh"
19270         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19271                 skip_env "Need to mount OST to test"
19272         fi
19273
19274         local mds=$(facet_host $SINGLEMDS)
19275         local target=$(do_nodes $mds 'lctl dl' |
19276                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19277
19278         local cmd1="file_count=1000 thrhi=4"
19279         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19280         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19281         local cmd="$cmd1 $cmd2 $cmd3"
19282
19283         rm -f ${TMP}/mds_survey*
19284         echo + $cmd
19285         eval $cmd || error "mds-survey with stripe_count failed"
19286         cat ${TMP}/mds_survey*
19287         rm -f ${TMP}/mds_survey*
19288 }
19289 run_test 225b "Metadata survey sanity with stripe_count = 1"
19290
19291 mcreate_path2fid () {
19292         local mode=$1
19293         local major=$2
19294         local minor=$3
19295         local name=$4
19296         local desc=$5
19297         local path=$DIR/$tdir/$name
19298         local fid
19299         local rc
19300         local fid_path
19301
19302         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19303                 error "cannot create $desc"
19304
19305         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19306         rc=$?
19307         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19308
19309         fid_path=$($LFS fid2path $MOUNT $fid)
19310         rc=$?
19311         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19312
19313         [ "$path" == "$fid_path" ] ||
19314                 error "fid2path returned $fid_path, expected $path"
19315
19316         echo "pass with $path and $fid"
19317 }
19318
19319 test_226a () {
19320         rm -rf $DIR/$tdir
19321         mkdir -p $DIR/$tdir
19322
19323         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19324         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19325         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19326         mcreate_path2fid 0040666 0 0 dir "directory"
19327         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19328         mcreate_path2fid 0100666 0 0 file "regular file"
19329         mcreate_path2fid 0120666 0 0 link "symbolic link"
19330         mcreate_path2fid 0140666 0 0 sock "socket"
19331 }
19332 run_test 226a "call path2fid and fid2path on files of all type"
19333
19334 test_226b () {
19335         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19336
19337         local MDTIDX=1
19338
19339         rm -rf $DIR/$tdir
19340         mkdir -p $DIR/$tdir
19341         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19342                 error "create remote directory failed"
19343         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19344         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19345                                 "character special file (null)"
19346         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19347                                 "character special file (no device)"
19348         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19349         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19350                                 "block special file (loop)"
19351         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19352         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19353         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19354 }
19355 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19356
19357 test_226c () {
19358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19359         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19360                 skip "Need MDS version at least 2.13.55"
19361
19362         local submnt=/mnt/submnt
19363         local srcfile=/etc/passwd
19364         local dstfile=$submnt/passwd
19365         local path
19366         local fid
19367
19368         rm -rf $DIR/$tdir
19369         rm -rf $submnt
19370         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19371                 error "create remote directory failed"
19372         mkdir -p $submnt || error "create $submnt failed"
19373         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19374                 error "mount $submnt failed"
19375         stack_trap "umount $submnt" EXIT
19376
19377         cp $srcfile $dstfile
19378         fid=$($LFS path2fid $dstfile)
19379         path=$($LFS fid2path $submnt "$fid")
19380         [ "$path" = "$dstfile" ] ||
19381                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19382 }
19383 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19384
19385 # LU-1299 Executing or running ldd on a truncated executable does not
19386 # cause an out-of-memory condition.
19387 test_227() {
19388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19389         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19390
19391         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19392         chmod +x $MOUNT/date
19393
19394         $MOUNT/date > /dev/null
19395         ldd $MOUNT/date > /dev/null
19396         rm -f $MOUNT/date
19397 }
19398 run_test 227 "running truncated executable does not cause OOM"
19399
19400 # LU-1512 try to reuse idle OI blocks
19401 test_228a() {
19402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19403         remote_mds_nodsh && skip "remote MDS with nodsh"
19404         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19405
19406         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19407         local myDIR=$DIR/$tdir
19408
19409         mkdir -p $myDIR
19410         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19411         $LCTL set_param fail_loc=0x80001002
19412         createmany -o $myDIR/t- 10000
19413         $LCTL set_param fail_loc=0
19414         # The guard is current the largest FID holder
19415         touch $myDIR/guard
19416         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19417                     tr -d '[')
19418         local IDX=$(($SEQ % 64))
19419
19420         do_facet $SINGLEMDS sync
19421         # Make sure journal flushed.
19422         sleep 6
19423         local blk1=$(do_facet $SINGLEMDS \
19424                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19425                      grep Blockcount | awk '{print $4}')
19426
19427         # Remove old files, some OI blocks will become idle.
19428         unlinkmany $myDIR/t- 10000
19429         # Create new files, idle OI blocks should be reused.
19430         createmany -o $myDIR/t- 2000
19431         do_facet $SINGLEMDS sync
19432         # Make sure journal flushed.
19433         sleep 6
19434         local blk2=$(do_facet $SINGLEMDS \
19435                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19436                      grep Blockcount | awk '{print $4}')
19437
19438         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19439 }
19440 run_test 228a "try to reuse idle OI blocks"
19441
19442 test_228b() {
19443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19444         remote_mds_nodsh && skip "remote MDS with nodsh"
19445         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19446
19447         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19448         local myDIR=$DIR/$tdir
19449
19450         mkdir -p $myDIR
19451         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19452         $LCTL set_param fail_loc=0x80001002
19453         createmany -o $myDIR/t- 10000
19454         $LCTL set_param fail_loc=0
19455         # The guard is current the largest FID holder
19456         touch $myDIR/guard
19457         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19458                     tr -d '[')
19459         local IDX=$(($SEQ % 64))
19460
19461         do_facet $SINGLEMDS sync
19462         # Make sure journal flushed.
19463         sleep 6
19464         local blk1=$(do_facet $SINGLEMDS \
19465                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19466                      grep Blockcount | awk '{print $4}')
19467
19468         # Remove old files, some OI blocks will become idle.
19469         unlinkmany $myDIR/t- 10000
19470
19471         # stop the MDT
19472         stop $SINGLEMDS || error "Fail to stop MDT."
19473         # remount the MDT
19474         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19475                 error "Fail to start MDT."
19476
19477         df $MOUNT || error "Fail to df."
19478         # Create new files, idle OI blocks should be reused.
19479         createmany -o $myDIR/t- 2000
19480         do_facet $SINGLEMDS sync
19481         # Make sure journal flushed.
19482         sleep 6
19483         local blk2=$(do_facet $SINGLEMDS \
19484                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19485                      grep Blockcount | awk '{print $4}')
19486
19487         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19488 }
19489 run_test 228b "idle OI blocks can be reused after MDT restart"
19490
19491 #LU-1881
19492 test_228c() {
19493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19494         remote_mds_nodsh && skip "remote MDS with nodsh"
19495         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19496
19497         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19498         local myDIR=$DIR/$tdir
19499
19500         mkdir -p $myDIR
19501         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19502         $LCTL set_param fail_loc=0x80001002
19503         # 20000 files can guarantee there are index nodes in the OI file
19504         createmany -o $myDIR/t- 20000
19505         $LCTL set_param fail_loc=0
19506         # The guard is current the largest FID holder
19507         touch $myDIR/guard
19508         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19509                     tr -d '[')
19510         local IDX=$(($SEQ % 64))
19511
19512         do_facet $SINGLEMDS sync
19513         # Make sure journal flushed.
19514         sleep 6
19515         local blk1=$(do_facet $SINGLEMDS \
19516                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19517                      grep Blockcount | awk '{print $4}')
19518
19519         # Remove old files, some OI blocks will become idle.
19520         unlinkmany $myDIR/t- 20000
19521         rm -f $myDIR/guard
19522         # The OI file should become empty now
19523
19524         # Create new files, idle OI blocks should be reused.
19525         createmany -o $myDIR/t- 2000
19526         do_facet $SINGLEMDS sync
19527         # Make sure journal flushed.
19528         sleep 6
19529         local blk2=$(do_facet $SINGLEMDS \
19530                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19531                      grep Blockcount | awk '{print $4}')
19532
19533         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19534 }
19535 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19536
19537 test_229() { # LU-2482, LU-3448
19538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19539         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19540         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19541                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19542
19543         rm -f $DIR/$tfile
19544
19545         # Create a file with a released layout and stripe count 2.
19546         $MULTIOP $DIR/$tfile H2c ||
19547                 error "failed to create file with released layout"
19548
19549         $LFS getstripe -v $DIR/$tfile
19550
19551         local pattern=$($LFS getstripe -L $DIR/$tfile)
19552         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19553
19554         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19555                 error "getstripe"
19556         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19557         stat $DIR/$tfile || error "failed to stat released file"
19558
19559         chown $RUNAS_ID $DIR/$tfile ||
19560                 error "chown $RUNAS_ID $DIR/$tfile failed"
19561
19562         chgrp $RUNAS_ID $DIR/$tfile ||
19563                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19564
19565         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19566         rm $DIR/$tfile || error "failed to remove released file"
19567 }
19568 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19569
19570 test_230a() {
19571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19572         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19573         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19574                 skip "Need MDS version at least 2.11.52"
19575
19576         local MDTIDX=1
19577
19578         test_mkdir $DIR/$tdir
19579         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19580         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19581         [ $mdt_idx -ne 0 ] &&
19582                 error "create local directory on wrong MDT $mdt_idx"
19583
19584         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19585                         error "create remote directory failed"
19586         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19587         [ $mdt_idx -ne $MDTIDX ] &&
19588                 error "create remote directory on wrong MDT $mdt_idx"
19589
19590         createmany -o $DIR/$tdir/test_230/t- 10 ||
19591                 error "create files on remote directory failed"
19592         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19593         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19594         rm -r $DIR/$tdir || error "unlink remote directory failed"
19595 }
19596 run_test 230a "Create remote directory and files under the remote directory"
19597
19598 test_230b() {
19599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19600         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19601         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19602                 skip "Need MDS version at least 2.11.52"
19603
19604         local MDTIDX=1
19605         local mdt_index
19606         local i
19607         local file
19608         local pid
19609         local stripe_count
19610         local migrate_dir=$DIR/$tdir/migrate_dir
19611         local other_dir=$DIR/$tdir/other_dir
19612
19613         test_mkdir $DIR/$tdir
19614         test_mkdir -i0 -c1 $migrate_dir
19615         test_mkdir -i0 -c1 $other_dir
19616         for ((i=0; i<10; i++)); do
19617                 mkdir -p $migrate_dir/dir_${i}
19618                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19619                         error "create files under remote dir failed $i"
19620         done
19621
19622         cp /etc/passwd $migrate_dir/$tfile
19623         cp /etc/passwd $other_dir/$tfile
19624         chattr +SAD $migrate_dir
19625         chattr +SAD $migrate_dir/$tfile
19626
19627         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19628         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19629         local old_dir_mode=$(stat -c%f $migrate_dir)
19630         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19631
19632         mkdir -p $migrate_dir/dir_default_stripe2
19633         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19634         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19635
19636         mkdir -p $other_dir
19637         ln $migrate_dir/$tfile $other_dir/luna
19638         ln $migrate_dir/$tfile $migrate_dir/sofia
19639         ln $other_dir/$tfile $migrate_dir/david
19640         ln -s $migrate_dir/$tfile $other_dir/zachary
19641         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19642         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19643
19644         local len
19645         local lnktgt
19646
19647         # inline symlink
19648         for len in 58 59 60; do
19649                 lnktgt=$(str_repeat 'l' $len)
19650                 touch $migrate_dir/$lnktgt
19651                 ln -s $lnktgt $migrate_dir/${len}char_ln
19652         done
19653
19654         # PATH_MAX
19655         for len in 4094 4095; do
19656                 lnktgt=$(str_repeat 'l' $len)
19657                 ln -s $lnktgt $migrate_dir/${len}char_ln
19658         done
19659
19660         # NAME_MAX
19661         for len in 254 255; do
19662                 touch $migrate_dir/$(str_repeat 'l' $len)
19663         done
19664
19665         $LFS migrate -m $MDTIDX $migrate_dir ||
19666                 error "fails on migrating remote dir to MDT1"
19667
19668         echo "migratate to MDT1, then checking.."
19669         for ((i = 0; i < 10; i++)); do
19670                 for file in $(find $migrate_dir/dir_${i}); do
19671                         mdt_index=$($LFS getstripe -m $file)
19672                         # broken symlink getstripe will fail
19673                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19674                                 error "$file is not on MDT${MDTIDX}"
19675                 done
19676         done
19677
19678         # the multiple link file should still in MDT0
19679         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19680         [ $mdt_index == 0 ] ||
19681                 error "$file is not on MDT${MDTIDX}"
19682
19683         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19684         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19685                 error " expect $old_dir_flag get $new_dir_flag"
19686
19687         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19688         [ "$old_file_flag" = "$new_file_flag" ] ||
19689                 error " expect $old_file_flag get $new_file_flag"
19690
19691         local new_dir_mode=$(stat -c%f $migrate_dir)
19692         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19693                 error "expect mode $old_dir_mode get $new_dir_mode"
19694
19695         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19696         [ "$old_file_mode" = "$new_file_mode" ] ||
19697                 error "expect mode $old_file_mode get $new_file_mode"
19698
19699         diff /etc/passwd $migrate_dir/$tfile ||
19700                 error "$tfile different after migration"
19701
19702         diff /etc/passwd $other_dir/luna ||
19703                 error "luna different after migration"
19704
19705         diff /etc/passwd $migrate_dir/sofia ||
19706                 error "sofia different after migration"
19707
19708         diff /etc/passwd $migrate_dir/david ||
19709                 error "david different after migration"
19710
19711         diff /etc/passwd $other_dir/zachary ||
19712                 error "zachary different after migration"
19713
19714         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19715                 error "${tfile}_ln different after migration"
19716
19717         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19718                 error "${tfile}_ln_other different after migration"
19719
19720         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19721         [ $stripe_count = 2 ] ||
19722                 error "dir strpe_count $d != 2 after migration."
19723
19724         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19725         [ $stripe_count = 2 ] ||
19726                 error "file strpe_count $d != 2 after migration."
19727
19728         #migrate back to MDT0
19729         MDTIDX=0
19730
19731         $LFS migrate -m $MDTIDX $migrate_dir ||
19732                 error "fails on migrating remote dir to MDT0"
19733
19734         echo "migrate back to MDT0, checking.."
19735         for file in $(find $migrate_dir); do
19736                 mdt_index=$($LFS getstripe -m $file)
19737                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19738                         error "$file is not on MDT${MDTIDX}"
19739         done
19740
19741         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19742         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19743                 error " expect $old_dir_flag get $new_dir_flag"
19744
19745         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19746         [ "$old_file_flag" = "$new_file_flag" ] ||
19747                 error " expect $old_file_flag get $new_file_flag"
19748
19749         local new_dir_mode=$(stat -c%f $migrate_dir)
19750         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19751                 error "expect mode $old_dir_mode get $new_dir_mode"
19752
19753         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19754         [ "$old_file_mode" = "$new_file_mode" ] ||
19755                 error "expect mode $old_file_mode get $new_file_mode"
19756
19757         diff /etc/passwd ${migrate_dir}/$tfile ||
19758                 error "$tfile different after migration"
19759
19760         diff /etc/passwd ${other_dir}/luna ||
19761                 error "luna different after migration"
19762
19763         diff /etc/passwd ${migrate_dir}/sofia ||
19764                 error "sofia different after migration"
19765
19766         diff /etc/passwd ${other_dir}/zachary ||
19767                 error "zachary different after migration"
19768
19769         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19770                 error "${tfile}_ln different after migration"
19771
19772         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19773                 error "${tfile}_ln_other different after migration"
19774
19775         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19776         [ $stripe_count = 2 ] ||
19777                 error "dir strpe_count $d != 2 after migration."
19778
19779         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19780         [ $stripe_count = 2 ] ||
19781                 error "file strpe_count $d != 2 after migration."
19782
19783         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19784 }
19785 run_test 230b "migrate directory"
19786
19787 test_230c() {
19788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19789         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19790         remote_mds_nodsh && skip "remote MDS with nodsh"
19791         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19792                 skip "Need MDS version at least 2.11.52"
19793
19794         local MDTIDX=1
19795         local total=3
19796         local mdt_index
19797         local file
19798         local migrate_dir=$DIR/$tdir/migrate_dir
19799
19800         #If migrating directory fails in the middle, all entries of
19801         #the directory is still accessiable.
19802         test_mkdir $DIR/$tdir
19803         test_mkdir -i0 -c1 $migrate_dir
19804         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19805         stat $migrate_dir
19806         createmany -o $migrate_dir/f $total ||
19807                 error "create files under ${migrate_dir} failed"
19808
19809         # fail after migrating top dir, and this will fail only once, so the
19810         # first sub file migration will fail (currently f3), others succeed.
19811         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19812         do_facet mds1 lctl set_param fail_loc=0x1801
19813         local t=$(ls $migrate_dir | wc -l)
19814         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19815                 error "migrate should fail"
19816         local u=$(ls $migrate_dir | wc -l)
19817         [ "$u" == "$t" ] || error "$u != $t during migration"
19818
19819         # add new dir/file should succeed
19820         mkdir $migrate_dir/dir ||
19821                 error "mkdir failed under migrating directory"
19822         touch $migrate_dir/file ||
19823                 error "create file failed under migrating directory"
19824
19825         # add file with existing name should fail
19826         for file in $migrate_dir/f*; do
19827                 stat $file > /dev/null || error "stat $file failed"
19828                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19829                         error "open(O_CREAT|O_EXCL) $file should fail"
19830                 $MULTIOP $file m && error "create $file should fail"
19831                 touch $DIR/$tdir/remote_dir/$tfile ||
19832                         error "touch $tfile failed"
19833                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19834                         error "link $file should fail"
19835                 mdt_index=$($LFS getstripe -m $file)
19836                 if [ $mdt_index == 0 ]; then
19837                         # file failed to migrate is not allowed to rename to
19838                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19839                                 error "rename to $file should fail"
19840                 else
19841                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19842                                 error "rename to $file failed"
19843                 fi
19844                 echo hello >> $file || error "write $file failed"
19845         done
19846
19847         # resume migration with different options should fail
19848         $LFS migrate -m 0 $migrate_dir &&
19849                 error "migrate -m 0 $migrate_dir should fail"
19850
19851         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19852                 error "migrate -c 2 $migrate_dir should fail"
19853
19854         # resume migration should succeed
19855         $LFS migrate -m $MDTIDX $migrate_dir ||
19856                 error "migrate $migrate_dir failed"
19857
19858         echo "Finish migration, then checking.."
19859         for file in $(find $migrate_dir); do
19860                 mdt_index=$($LFS getstripe -m $file)
19861                 [ $mdt_index == $MDTIDX ] ||
19862                         error "$file is not on MDT${MDTIDX}"
19863         done
19864
19865         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19866 }
19867 run_test 230c "check directory accessiblity if migration failed"
19868
19869 test_230d() {
19870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19871         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19872         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19873                 skip "Need MDS version at least 2.11.52"
19874         # LU-11235
19875         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19876
19877         local migrate_dir=$DIR/$tdir/migrate_dir
19878         local old_index
19879         local new_index
19880         local old_count
19881         local new_count
19882         local new_hash
19883         local mdt_index
19884         local i
19885         local j
19886
19887         old_index=$((RANDOM % MDSCOUNT))
19888         old_count=$((MDSCOUNT - old_index))
19889         new_index=$((RANDOM % MDSCOUNT))
19890         new_count=$((MDSCOUNT - new_index))
19891         new_hash=1 # for all_char
19892
19893         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19894         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19895
19896         test_mkdir $DIR/$tdir
19897         test_mkdir -i $old_index -c $old_count $migrate_dir
19898
19899         for ((i=0; i<100; i++)); do
19900                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19901                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19902                         error "create files under remote dir failed $i"
19903         done
19904
19905         echo -n "Migrate from MDT$old_index "
19906         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19907         echo -n "to MDT$new_index"
19908         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19909         echo
19910
19911         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19912         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19913                 error "migrate remote dir error"
19914
19915         echo "Finish migration, then checking.."
19916         for file in $(find $migrate_dir -maxdepth 1); do
19917                 mdt_index=$($LFS getstripe -m $file)
19918                 if [ $mdt_index -lt $new_index ] ||
19919                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19920                         error "$file is on MDT$mdt_index"
19921                 fi
19922         done
19923
19924         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19925 }
19926 run_test 230d "check migrate big directory"
19927
19928 test_230e() {
19929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19930         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19931         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19932                 skip "Need MDS version at least 2.11.52"
19933
19934         local i
19935         local j
19936         local a_fid
19937         local b_fid
19938
19939         mkdir_on_mdt0 $DIR/$tdir
19940         mkdir $DIR/$tdir/migrate_dir
19941         mkdir $DIR/$tdir/other_dir
19942         touch $DIR/$tdir/migrate_dir/a
19943         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19944         ls $DIR/$tdir/other_dir
19945
19946         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19947                 error "migrate dir fails"
19948
19949         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19950         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19951
19952         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19953         [ $mdt_index == 0 ] || error "a is not on MDT0"
19954
19955         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19956                 error "migrate dir fails"
19957
19958         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19959         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19960
19961         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19962         [ $mdt_index == 1 ] || error "a is not on MDT1"
19963
19964         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19965         [ $mdt_index == 1 ] || error "b is not on MDT1"
19966
19967         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19968         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19969
19970         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19971
19972         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19973 }
19974 run_test 230e "migrate mulitple local link files"
19975
19976 test_230f() {
19977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19978         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19979         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19980                 skip "Need MDS version at least 2.11.52"
19981
19982         local a_fid
19983         local ln_fid
19984
19985         mkdir -p $DIR/$tdir
19986         mkdir $DIR/$tdir/migrate_dir
19987         $LFS mkdir -i1 $DIR/$tdir/other_dir
19988         touch $DIR/$tdir/migrate_dir/a
19989         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19990         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19991         ls $DIR/$tdir/other_dir
19992
19993         # a should be migrated to MDT1, since no other links on MDT0
19994         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19995                 error "#1 migrate dir fails"
19996         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19997         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19998         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19999         [ $mdt_index == 1 ] || error "a is not on MDT1"
20000
20001         # a should stay on MDT1, because it is a mulitple link file
20002         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20003                 error "#2 migrate dir fails"
20004         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20005         [ $mdt_index == 1 ] || error "a is not on MDT1"
20006
20007         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20008                 error "#3 migrate dir fails"
20009
20010         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20011         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20012         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20013
20014         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20015         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20016
20017         # a should be migrated to MDT0, since no other links on MDT1
20018         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20019                 error "#4 migrate dir fails"
20020         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20021         [ $mdt_index == 0 ] || error "a is not on MDT0"
20022
20023         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20024 }
20025 run_test 230f "migrate mulitple remote link files"
20026
20027 test_230g() {
20028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20029         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20030         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20031                 skip "Need MDS version at least 2.11.52"
20032
20033         mkdir -p $DIR/$tdir/migrate_dir
20034
20035         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20036                 error "migrating dir to non-exist MDT succeeds"
20037         true
20038 }
20039 run_test 230g "migrate dir to non-exist MDT"
20040
20041 test_230h() {
20042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20043         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20044         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20045                 skip "Need MDS version at least 2.11.52"
20046
20047         local mdt_index
20048
20049         mkdir -p $DIR/$tdir/migrate_dir
20050
20051         $LFS migrate -m1 $DIR &&
20052                 error "migrating mountpoint1 should fail"
20053
20054         $LFS migrate -m1 $DIR/$tdir/.. &&
20055                 error "migrating mountpoint2 should fail"
20056
20057         # same as mv
20058         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20059                 error "migrating $tdir/migrate_dir/.. should fail"
20060
20061         true
20062 }
20063 run_test 230h "migrate .. and root"
20064
20065 test_230i() {
20066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20068         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20069                 skip "Need MDS version at least 2.11.52"
20070
20071         mkdir -p $DIR/$tdir/migrate_dir
20072
20073         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20074                 error "migration fails with a tailing slash"
20075
20076         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20077                 error "migration fails with two tailing slashes"
20078 }
20079 run_test 230i "lfs migrate -m tolerates trailing slashes"
20080
20081 test_230j() {
20082         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20083         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20084                 skip "Need MDS version at least 2.11.52"
20085
20086         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20087         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20088                 error "create $tfile failed"
20089         cat /etc/passwd > $DIR/$tdir/$tfile
20090
20091         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20092
20093         cmp /etc/passwd $DIR/$tdir/$tfile ||
20094                 error "DoM file mismatch after migration"
20095 }
20096 run_test 230j "DoM file data not changed after dir migration"
20097
20098 test_230k() {
20099         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20100         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20101                 skip "Need MDS version at least 2.11.56"
20102
20103         local total=20
20104         local files_on_starting_mdt=0
20105
20106         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20107         $LFS getdirstripe $DIR/$tdir
20108         for i in $(seq $total); do
20109                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20110                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20111                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20112         done
20113
20114         echo "$files_on_starting_mdt files on MDT0"
20115
20116         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20117         $LFS getdirstripe $DIR/$tdir
20118
20119         files_on_starting_mdt=0
20120         for i in $(seq $total); do
20121                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20122                         error "file $tfile.$i mismatch after migration"
20123                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20124                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20125         done
20126
20127         echo "$files_on_starting_mdt files on MDT1 after migration"
20128         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20129
20130         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20131         $LFS getdirstripe $DIR/$tdir
20132
20133         files_on_starting_mdt=0
20134         for i in $(seq $total); do
20135                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20136                         error "file $tfile.$i mismatch after 2nd migration"
20137                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20138                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20139         done
20140
20141         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20142         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20143
20144         true
20145 }
20146 run_test 230k "file data not changed after dir migration"
20147
20148 test_230l() {
20149         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20150         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20151                 skip "Need MDS version at least 2.11.56"
20152
20153         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20154         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20155                 error "create files under remote dir failed $i"
20156         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20157 }
20158 run_test 230l "readdir between MDTs won't crash"
20159
20160 test_230m() {
20161         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20162         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20163                 skip "Need MDS version at least 2.11.56"
20164
20165         local MDTIDX=1
20166         local mig_dir=$DIR/$tdir/migrate_dir
20167         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20168         local shortstr="b"
20169         local val
20170
20171         echo "Creating files and dirs with xattrs"
20172         test_mkdir $DIR/$tdir
20173         test_mkdir -i0 -c1 $mig_dir
20174         mkdir $mig_dir/dir
20175         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20176                 error "cannot set xattr attr1 on dir"
20177         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20178                 error "cannot set xattr attr2 on dir"
20179         touch $mig_dir/dir/f0
20180         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20181                 error "cannot set xattr attr1 on file"
20182         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20183                 error "cannot set xattr attr2 on file"
20184         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20185         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20186         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20187         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20188         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20189         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20190         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20191         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20192         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20193
20194         echo "Migrating to MDT1"
20195         $LFS migrate -m $MDTIDX $mig_dir ||
20196                 error "fails on migrating dir to MDT1"
20197
20198         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20199         echo "Checking xattrs"
20200         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20201         [ "$val" = $longstr ] ||
20202                 error "expecting xattr1 $longstr on dir, found $val"
20203         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20204         [ "$val" = $shortstr ] ||
20205                 error "expecting xattr2 $shortstr on dir, found $val"
20206         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20207         [ "$val" = $longstr ] ||
20208                 error "expecting xattr1 $longstr on file, found $val"
20209         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20210         [ "$val" = $shortstr ] ||
20211                 error "expecting xattr2 $shortstr on file, found $val"
20212 }
20213 run_test 230m "xattrs not changed after dir migration"
20214
20215 test_230n() {
20216         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20217         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20218                 skip "Need MDS version at least 2.13.53"
20219
20220         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20221         cat /etc/hosts > $DIR/$tdir/$tfile
20222         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20223         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20224
20225         cmp /etc/hosts $DIR/$tdir/$tfile ||
20226                 error "File data mismatch after migration"
20227 }
20228 run_test 230n "Dir migration with mirrored file"
20229
20230 test_230o() {
20231         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20232         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20233                 skip "Need MDS version at least 2.13.52"
20234
20235         local mdts=$(comma_list $(mdts_nodes))
20236         local timeout=100
20237         local restripe_status
20238         local delta
20239         local i
20240
20241         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20242
20243         # in case "crush" hash type is not set
20244         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20245
20246         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20247                            mdt.*MDT0000.enable_dir_restripe)
20248         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20249         stack_trap "do_nodes $mdts $LCTL set_param \
20250                     mdt.*.enable_dir_restripe=$restripe_status"
20251
20252         mkdir $DIR/$tdir
20253         createmany -m $DIR/$tdir/f 100 ||
20254                 error "create files under remote dir failed $i"
20255         createmany -d $DIR/$tdir/d 100 ||
20256                 error "create dirs under remote dir failed $i"
20257
20258         for i in $(seq 2 $MDSCOUNT); do
20259                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20260                 $LFS setdirstripe -c $i $DIR/$tdir ||
20261                         error "split -c $i $tdir failed"
20262                 wait_update $HOSTNAME \
20263                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20264                         error "dir split not finished"
20265                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20266                         awk '/migrate/ {sum += $2} END { print sum }')
20267                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20268                 # delta is around total_files/stripe_count
20269                 (( $delta < 200 / (i - 1) + 4 )) ||
20270                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20271         done
20272 }
20273 run_test 230o "dir split"
20274
20275 test_230p() {
20276         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20277         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20278                 skip "Need MDS version at least 2.13.52"
20279
20280         local mdts=$(comma_list $(mdts_nodes))
20281         local timeout=100
20282         local restripe_status
20283         local delta
20284         local c
20285
20286         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20287
20288         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20289
20290         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20291                            mdt.*MDT0000.enable_dir_restripe)
20292         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20293         stack_trap "do_nodes $mdts $LCTL set_param \
20294                     mdt.*.enable_dir_restripe=$restripe_status"
20295
20296         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20297         createmany -m $DIR/$tdir/f 100 ||
20298                 error "create files under remote dir failed"
20299         createmany -d $DIR/$tdir/d 100 ||
20300                 error "create dirs under remote dir failed"
20301
20302         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20303                 local mdt_hash="crush"
20304
20305                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20306                 $LFS setdirstripe -c $c $DIR/$tdir ||
20307                         error "split -c $c $tdir failed"
20308                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20309                         mdt_hash="$mdt_hash,fixed"
20310                 elif [ $c -eq 1 ]; then
20311                         mdt_hash="none"
20312                 fi
20313                 wait_update $HOSTNAME \
20314                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20315                         error "dir merge not finished"
20316                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20317                         awk '/migrate/ {sum += $2} END { print sum }')
20318                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20319                 # delta is around total_files/stripe_count
20320                 (( delta < 200 / c + 4 )) ||
20321                         error "$delta files migrated >= $((200 / c + 4))"
20322         done
20323 }
20324 run_test 230p "dir merge"
20325
20326 test_230q() {
20327         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20328         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20329                 skip "Need MDS version at least 2.13.52"
20330
20331         local mdts=$(comma_list $(mdts_nodes))
20332         local saved_threshold=$(do_facet mds1 \
20333                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20334         local saved_delta=$(do_facet mds1 \
20335                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20336         local threshold=100
20337         local delta=2
20338         local total=0
20339         local stripe_count=0
20340         local stripe_index
20341         local nr_files
20342         local create
20343
20344         # test with fewer files on ZFS
20345         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20346
20347         stack_trap "do_nodes $mdts $LCTL set_param \
20348                     mdt.*.dir_split_count=$saved_threshold"
20349         stack_trap "do_nodes $mdts $LCTL set_param \
20350                     mdt.*.dir_split_delta=$saved_delta"
20351         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20352         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20353         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20354         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20355         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20356         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20357
20358         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20359         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20360
20361         create=$((threshold * 3 / 2))
20362         while [ $stripe_count -lt $MDSCOUNT ]; do
20363                 createmany -m $DIR/$tdir/f $total $create ||
20364                         error "create sub files failed"
20365                 stat $DIR/$tdir > /dev/null
20366                 total=$((total + create))
20367                 stripe_count=$((stripe_count + delta))
20368                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20369
20370                 wait_update $HOSTNAME \
20371                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20372                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20373
20374                 wait_update $HOSTNAME \
20375                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20376                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20377
20378                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20379                 echo "$nr_files/$total files on MDT$stripe_index after split"
20380                 # allow 10% margin of imbalance with crush hash
20381                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20382                         error "$nr_files files on MDT$stripe_index after split"
20383
20384                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20385                 [ $nr_files -eq $total ] ||
20386                         error "total sub files $nr_files != $total"
20387         done
20388
20389         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20390
20391         echo "fixed layout directory won't auto split"
20392         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20393         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20394                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20395         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20396                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20397 }
20398 run_test 230q "dir auto split"
20399
20400 test_230r() {
20401         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20402         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20403         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20404                 skip "Need MDS version at least 2.13.54"
20405
20406         # maximum amount of local locks:
20407         # parent striped dir - 2 locks
20408         # new stripe in parent to migrate to - 1 lock
20409         # source and target - 2 locks
20410         # Total 5 locks for regular file
20411         mkdir -p $DIR/$tdir
20412         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20413         touch $DIR/$tdir/dir1/eee
20414
20415         # create 4 hardlink for 4 more locks
20416         # Total: 9 locks > RS_MAX_LOCKS (8)
20417         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20418         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20419         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20420         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20421         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20422         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20423         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20424         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20425
20426         cancel_lru_locks mdc
20427
20428         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20429                 error "migrate dir fails"
20430
20431         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20432 }
20433 run_test 230r "migrate with too many local locks"
20434
20435 test_230s() {
20436         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20437                 skip "Need MDS version at least 2.14.52"
20438
20439         local mdts=$(comma_list $(mdts_nodes))
20440         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20441                                 mdt.*MDT0000.enable_dir_restripe)
20442
20443         stack_trap "do_nodes $mdts $LCTL set_param \
20444                     mdt.*.enable_dir_restripe=$restripe_status"
20445
20446         local st
20447         for st in 0 1; do
20448                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20449                 test_mkdir $DIR/$tdir
20450                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20451                         error "$LFS mkdir should return EEXIST if target exists"
20452                 rmdir $DIR/$tdir
20453         done
20454 }
20455 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20456
20457 test_230t()
20458 {
20459         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20460         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20461                 skip "Need MDS version at least 2.14.50"
20462
20463         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20464         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20465         $LFS project -p 1 -s $DIR/$tdir ||
20466                 error "set $tdir project id failed"
20467         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20468                 error "set subdir project id failed"
20469         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20470 }
20471 run_test 230t "migrate directory with project ID set"
20472
20473 test_230u()
20474 {
20475         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20476         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20477                 skip "Need MDS version at least 2.14.53"
20478
20479         local count
20480
20481         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20482         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20483         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20484         for i in $(seq 0 $((MDSCOUNT - 1))); do
20485                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20486                 echo "$count dirs migrated to MDT$i"
20487         done
20488         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20489         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20490 }
20491 run_test 230u "migrate directory by QOS"
20492
20493 test_230v()
20494 {
20495         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20496         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20497                 skip "Need MDS version at least 2.14.53"
20498
20499         local count
20500
20501         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20502         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20503         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20504         for i in $(seq 0 $((MDSCOUNT - 1))); do
20505                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20506                 echo "$count subdirs migrated to MDT$i"
20507                 (( i == 3 )) && (( count > 0 )) &&
20508                         error "subdir shouldn't be migrated to MDT3"
20509         done
20510         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20511         (( count == 3 )) || error "dirs migrated to $count MDTs"
20512 }
20513 run_test 230v "subdir migrated to the MDT where its parent is located"
20514
20515 test_230w() {
20516         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20517         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20518                 skip "Need MDS version at least 2.14.53"
20519
20520         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20521
20522         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20523                 error "migrate failed"
20524
20525         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20526                 error "$tdir stripe count mismatch"
20527
20528         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20529                 error "$tdir/sub is striped"
20530 }
20531 run_test 230w "non-recursive mode dir migration"
20532
20533 test_231a()
20534 {
20535         # For simplicity this test assumes that max_pages_per_rpc
20536         # is the same across all OSCs
20537         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20538         local bulk_size=$((max_pages * PAGE_SIZE))
20539         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20540                                        head -n 1)
20541
20542         mkdir -p $DIR/$tdir
20543         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20544                 error "failed to set stripe with -S ${brw_size}M option"
20545
20546         # clear the OSC stats
20547         $LCTL set_param osc.*.stats=0 &>/dev/null
20548         stop_writeback
20549
20550         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20551         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20552                 oflag=direct &>/dev/null || error "dd failed"
20553
20554         sync; sleep 1; sync # just to be safe
20555         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20556         if [ x$nrpcs != "x1" ]; then
20557                 $LCTL get_param osc.*.stats
20558                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20559         fi
20560
20561         start_writeback
20562         # Drop the OSC cache, otherwise we will read from it
20563         cancel_lru_locks osc
20564
20565         # clear the OSC stats
20566         $LCTL set_param osc.*.stats=0 &>/dev/null
20567
20568         # Client reads $bulk_size.
20569         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20570                 iflag=direct &>/dev/null || error "dd failed"
20571
20572         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20573         if [ x$nrpcs != "x1" ]; then
20574                 $LCTL get_param osc.*.stats
20575                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20576         fi
20577 }
20578 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20579
20580 test_231b() {
20581         mkdir -p $DIR/$tdir
20582         local i
20583         for i in {0..1023}; do
20584                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20585                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20586                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20587         done
20588         sync
20589 }
20590 run_test 231b "must not assert on fully utilized OST request buffer"
20591
20592 test_232a() {
20593         mkdir -p $DIR/$tdir
20594         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20595
20596         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20597         do_facet ost1 $LCTL set_param fail_loc=0x31c
20598
20599         # ignore dd failure
20600         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20601
20602         do_facet ost1 $LCTL set_param fail_loc=0
20603         umount_client $MOUNT || error "umount failed"
20604         mount_client $MOUNT || error "mount failed"
20605         stop ost1 || error "cannot stop ost1"
20606         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20607 }
20608 run_test 232a "failed lock should not block umount"
20609
20610 test_232b() {
20611         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20612                 skip "Need MDS version at least 2.10.58"
20613
20614         mkdir -p $DIR/$tdir
20615         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20616         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20617         sync
20618         cancel_lru_locks osc
20619
20620         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20621         do_facet ost1 $LCTL set_param fail_loc=0x31c
20622
20623         # ignore failure
20624         $LFS data_version $DIR/$tdir/$tfile || true
20625
20626         do_facet ost1 $LCTL set_param fail_loc=0
20627         umount_client $MOUNT || error "umount failed"
20628         mount_client $MOUNT || error "mount failed"
20629         stop ost1 || error "cannot stop ost1"
20630         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20631 }
20632 run_test 232b "failed data version lock should not block umount"
20633
20634 test_233a() {
20635         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20636                 skip "Need MDS version at least 2.3.64"
20637         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20638
20639         local fid=$($LFS path2fid $MOUNT)
20640
20641         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20642                 error "cannot access $MOUNT using its FID '$fid'"
20643 }
20644 run_test 233a "checking that OBF of the FS root succeeds"
20645
20646 test_233b() {
20647         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20648                 skip "Need MDS version at least 2.5.90"
20649         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20650
20651         local fid=$($LFS path2fid $MOUNT/.lustre)
20652
20653         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20654                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20655
20656         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20657         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20658                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20659 }
20660 run_test 233b "checking that OBF of the FS .lustre succeeds"
20661
20662 test_234() {
20663         local p="$TMP/sanityN-$TESTNAME.parameters"
20664         save_lustre_params client "llite.*.xattr_cache" > $p
20665         lctl set_param llite.*.xattr_cache 1 ||
20666                 skip_env "xattr cache is not supported"
20667
20668         mkdir -p $DIR/$tdir || error "mkdir failed"
20669         touch $DIR/$tdir/$tfile || error "touch failed"
20670         # OBD_FAIL_LLITE_XATTR_ENOMEM
20671         $LCTL set_param fail_loc=0x1405
20672         getfattr -n user.attr $DIR/$tdir/$tfile &&
20673                 error "getfattr should have failed with ENOMEM"
20674         $LCTL set_param fail_loc=0x0
20675         rm -rf $DIR/$tdir
20676
20677         restore_lustre_params < $p
20678         rm -f $p
20679 }
20680 run_test 234 "xattr cache should not crash on ENOMEM"
20681
20682 test_235() {
20683         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20684                 skip "Need MDS version at least 2.4.52"
20685
20686         flock_deadlock $DIR/$tfile
20687         local RC=$?
20688         case $RC in
20689                 0)
20690                 ;;
20691                 124) error "process hangs on a deadlock"
20692                 ;;
20693                 *) error "error executing flock_deadlock $DIR/$tfile"
20694                 ;;
20695         esac
20696 }
20697 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20698
20699 #LU-2935
20700 test_236() {
20701         check_swap_layouts_support
20702
20703         local ref1=/etc/passwd
20704         local ref2=/etc/group
20705         local file1=$DIR/$tdir/f1
20706         local file2=$DIR/$tdir/f2
20707
20708         test_mkdir -c1 $DIR/$tdir
20709         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20710         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20711         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20712         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20713         local fd=$(free_fd)
20714         local cmd="exec $fd<>$file2"
20715         eval $cmd
20716         rm $file2
20717         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20718                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20719         cmd="exec $fd>&-"
20720         eval $cmd
20721         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20722
20723         #cleanup
20724         rm -rf $DIR/$tdir
20725 }
20726 run_test 236 "Layout swap on open unlinked file"
20727
20728 # LU-4659 linkea consistency
20729 test_238() {
20730         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20731                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20732                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20733                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20734
20735         touch $DIR/$tfile
20736         ln $DIR/$tfile $DIR/$tfile.lnk
20737         touch $DIR/$tfile.new
20738         mv $DIR/$tfile.new $DIR/$tfile
20739         local fid1=$($LFS path2fid $DIR/$tfile)
20740         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20741         local path1=$($LFS fid2path $FSNAME "$fid1")
20742         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20743         local path2=$($LFS fid2path $FSNAME "$fid2")
20744         [ $tfile.lnk == $path2 ] ||
20745                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20746         rm -f $DIR/$tfile*
20747 }
20748 run_test 238 "Verify linkea consistency"
20749
20750 test_239A() { # was test_239
20751         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20752                 skip "Need MDS version at least 2.5.60"
20753
20754         local list=$(comma_list $(mdts_nodes))
20755
20756         mkdir -p $DIR/$tdir
20757         createmany -o $DIR/$tdir/f- 5000
20758         unlinkmany $DIR/$tdir/f- 5000
20759         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20760                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20761         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20762                         osp.*MDT*.sync_in_flight" | calc_sum)
20763         [ "$changes" -eq 0 ] || error "$changes not synced"
20764 }
20765 run_test 239A "osp_sync test"
20766
20767 test_239a() { #LU-5297
20768         remote_mds_nodsh && skip "remote MDS with nodsh"
20769
20770         touch $DIR/$tfile
20771         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20772         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20773         chgrp $RUNAS_GID $DIR/$tfile
20774         wait_delete_completed
20775 }
20776 run_test 239a "process invalid osp sync record correctly"
20777
20778 test_239b() { #LU-5297
20779         remote_mds_nodsh && skip "remote MDS with nodsh"
20780
20781         touch $DIR/$tfile1
20782         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20783         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20784         chgrp $RUNAS_GID $DIR/$tfile1
20785         wait_delete_completed
20786         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20787         touch $DIR/$tfile2
20788         chgrp $RUNAS_GID $DIR/$tfile2
20789         wait_delete_completed
20790 }
20791 run_test 239b "process osp sync record with ENOMEM error correctly"
20792
20793 test_240() {
20794         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20795         remote_mds_nodsh && skip "remote MDS with nodsh"
20796
20797         mkdir -p $DIR/$tdir
20798
20799         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20800                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20801         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20802                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20803
20804         umount_client $MOUNT || error "umount failed"
20805         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20806         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20807         mount_client $MOUNT || error "failed to mount client"
20808
20809         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20810         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20811 }
20812 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20813
20814 test_241_bio() {
20815         local count=$1
20816         local bsize=$2
20817
20818         for LOOP in $(seq $count); do
20819                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20820                 cancel_lru_locks $OSC || true
20821         done
20822 }
20823
20824 test_241_dio() {
20825         local count=$1
20826         local bsize=$2
20827
20828         for LOOP in $(seq $1); do
20829                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20830                         2>/dev/null
20831         done
20832 }
20833
20834 test_241a() { # was test_241
20835         local bsize=$PAGE_SIZE
20836
20837         (( bsize < 40960 )) && bsize=40960
20838         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20839         ls -la $DIR/$tfile
20840         cancel_lru_locks $OSC
20841         test_241_bio 1000 $bsize &
20842         PID=$!
20843         test_241_dio 1000 $bsize
20844         wait $PID
20845 }
20846 run_test 241a "bio vs dio"
20847
20848 test_241b() {
20849         local bsize=$PAGE_SIZE
20850
20851         (( bsize < 40960 )) && bsize=40960
20852         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20853         ls -la $DIR/$tfile
20854         test_241_dio 1000 $bsize &
20855         PID=$!
20856         test_241_dio 1000 $bsize
20857         wait $PID
20858 }
20859 run_test 241b "dio vs dio"
20860
20861 test_242() {
20862         remote_mds_nodsh && skip "remote MDS with nodsh"
20863
20864         mkdir_on_mdt0 $DIR/$tdir
20865         touch $DIR/$tdir/$tfile
20866
20867         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20868         do_facet mds1 lctl set_param fail_loc=0x105
20869         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20870
20871         do_facet mds1 lctl set_param fail_loc=0
20872         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20873 }
20874 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20875
20876 test_243()
20877 {
20878         test_mkdir $DIR/$tdir
20879         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20880 }
20881 run_test 243 "various group lock tests"
20882
20883 test_244a()
20884 {
20885         test_mkdir $DIR/$tdir
20886         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20887         sendfile_grouplock $DIR/$tdir/$tfile || \
20888                 error "sendfile+grouplock failed"
20889         rm -rf $DIR/$tdir
20890 }
20891 run_test 244a "sendfile with group lock tests"
20892
20893 test_244b()
20894 {
20895         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20896
20897         local threads=50
20898         local size=$((1024*1024))
20899
20900         test_mkdir $DIR/$tdir
20901         for i in $(seq 1 $threads); do
20902                 local file=$DIR/$tdir/file_$((i / 10))
20903                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20904                 local pids[$i]=$!
20905         done
20906         for i in $(seq 1 $threads); do
20907                 wait ${pids[$i]}
20908         done
20909 }
20910 run_test 244b "multi-threaded write with group lock"
20911
20912 test_245() {
20913         local flagname="multi_mod_rpcs"
20914         local connect_data_name="max_mod_rpcs"
20915         local out
20916
20917         # check if multiple modify RPCs flag is set
20918         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20919                 grep "connect_flags:")
20920         echo "$out"
20921
20922         echo "$out" | grep -qw $flagname
20923         if [ $? -ne 0 ]; then
20924                 echo "connect flag $flagname is not set"
20925                 return
20926         fi
20927
20928         # check if multiple modify RPCs data is set
20929         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20930         echo "$out"
20931
20932         echo "$out" | grep -qw $connect_data_name ||
20933                 error "import should have connect data $connect_data_name"
20934 }
20935 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20936
20937 cleanup_247() {
20938         local submount=$1
20939
20940         trap 0
20941         umount_client $submount
20942         rmdir $submount
20943 }
20944
20945 test_247a() {
20946         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20947                 grep -q subtree ||
20948                 skip_env "Fileset feature is not supported"
20949
20950         local submount=${MOUNT}_$tdir
20951
20952         mkdir $MOUNT/$tdir
20953         mkdir -p $submount || error "mkdir $submount failed"
20954         FILESET="$FILESET/$tdir" mount_client $submount ||
20955                 error "mount $submount failed"
20956         trap "cleanup_247 $submount" EXIT
20957         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20958         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20959                 error "read $MOUNT/$tdir/$tfile failed"
20960         cleanup_247 $submount
20961 }
20962 run_test 247a "mount subdir as fileset"
20963
20964 test_247b() {
20965         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20966                 skip_env "Fileset feature is not supported"
20967
20968         local submount=${MOUNT}_$tdir
20969
20970         rm -rf $MOUNT/$tdir
20971         mkdir -p $submount || error "mkdir $submount failed"
20972         SKIP_FILESET=1
20973         FILESET="$FILESET/$tdir" mount_client $submount &&
20974                 error "mount $submount should fail"
20975         rmdir $submount
20976 }
20977 run_test 247b "mount subdir that dose not exist"
20978
20979 test_247c() {
20980         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20981                 skip_env "Fileset feature is not supported"
20982
20983         local submount=${MOUNT}_$tdir
20984
20985         mkdir -p $MOUNT/$tdir/dir1
20986         mkdir -p $submount || error "mkdir $submount failed"
20987         trap "cleanup_247 $submount" EXIT
20988         FILESET="$FILESET/$tdir" mount_client $submount ||
20989                 error "mount $submount failed"
20990         local fid=$($LFS path2fid $MOUNT/)
20991         $LFS fid2path $submount $fid && error "fid2path should fail"
20992         cleanup_247 $submount
20993 }
20994 run_test 247c "running fid2path outside subdirectory root"
20995
20996 test_247d() {
20997         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20998                 skip "Fileset feature is not supported"
20999
21000         local submount=${MOUNT}_$tdir
21001
21002         mkdir -p $MOUNT/$tdir/dir1
21003         mkdir -p $submount || error "mkdir $submount failed"
21004         FILESET="$FILESET/$tdir" mount_client $submount ||
21005                 error "mount $submount failed"
21006         trap "cleanup_247 $submount" EXIT
21007
21008         local td=$submount/dir1
21009         local fid=$($LFS path2fid $td)
21010         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21011
21012         # check that we get the same pathname back
21013         local rootpath
21014         local found
21015         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21016                 echo "$rootpath $fid"
21017                 found=$($LFS fid2path $rootpath "$fid")
21018                 [ -n "$found" ] || error "fid2path should succeed"
21019                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21020         done
21021         # check wrong root path format
21022         rootpath=$submount"_wrong"
21023         found=$($LFS fid2path $rootpath "$fid")
21024         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21025
21026         cleanup_247 $submount
21027 }
21028 run_test 247d "running fid2path inside subdirectory root"
21029
21030 # LU-8037
21031 test_247e() {
21032         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21033                 grep -q subtree ||
21034                 skip "Fileset feature is not supported"
21035
21036         local submount=${MOUNT}_$tdir
21037
21038         mkdir $MOUNT/$tdir
21039         mkdir -p $submount || error "mkdir $submount failed"
21040         FILESET="$FILESET/.." mount_client $submount &&
21041                 error "mount $submount should fail"
21042         rmdir $submount
21043 }
21044 run_test 247e "mount .. as fileset"
21045
21046 test_247f() {
21047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21048         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21049                 skip "Need at least version 2.13.52"
21050         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21051                 skip "Need at least version 2.14.50"
21052         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21053                 grep -q subtree ||
21054                 skip "Fileset feature is not supported"
21055
21056         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21057         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21058                 error "mkdir remote failed"
21059         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21060                 error "mkdir remote/subdir failed"
21061         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21062                 error "mkdir striped failed"
21063         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21064
21065         local submount=${MOUNT}_$tdir
21066
21067         mkdir -p $submount || error "mkdir $submount failed"
21068         stack_trap "rmdir $submount"
21069
21070         local dir
21071         local stat
21072         local fileset=$FILESET
21073         local mdts=$(comma_list $(mdts_nodes))
21074
21075         stat=$(do_facet mds1 $LCTL get_param -n \
21076                 mdt.*MDT0000.enable_remote_subdir_mount)
21077         stack_trap "do_nodes $mdts $LCTL set_param \
21078                 mdt.*.enable_remote_subdir_mount=$stat"
21079
21080         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21081         stack_trap "umount_client $submount"
21082         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21083                 error "mount remote dir $dir should fail"
21084
21085         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21086                 $tdir/striped/. ; do
21087                 FILESET="$fileset/$dir" mount_client $submount ||
21088                         error "mount $dir failed"
21089                 umount_client $submount
21090         done
21091
21092         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21093         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21094                 error "mount $tdir/remote failed"
21095 }
21096 run_test 247f "mount striped or remote directory as fileset"
21097
21098 test_247g() {
21099         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21100         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21101                 skip "Need at least version 2.14.50"
21102
21103         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21104                 error "mkdir $tdir failed"
21105         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21106
21107         local submount=${MOUNT}_$tdir
21108
21109         mkdir -p $submount || error "mkdir $submount failed"
21110         stack_trap "rmdir $submount"
21111
21112         FILESET="$fileset/$tdir" mount_client $submount ||
21113                 error "mount $dir failed"
21114         stack_trap "umount $submount"
21115
21116         local mdts=$(comma_list $(mdts_nodes))
21117
21118         local nrpcs
21119
21120         stat $submount > /dev/null
21121         cancel_lru_locks $MDC
21122         stat $submount > /dev/null
21123         stat $submount/$tfile > /dev/null
21124         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21125         stat $submount/$tfile > /dev/null
21126         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21127                 awk '/getattr/ {sum += $2} END {print sum}')
21128
21129         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21130 }
21131 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21132
21133 test_248a() {
21134         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21135         [ -z "$fast_read_sav" ] && skip "no fast read support"
21136
21137         # create a large file for fast read verification
21138         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21139
21140         # make sure the file is created correctly
21141         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21142                 { rm -f $DIR/$tfile; skip "file creation error"; }
21143
21144         echo "Test 1: verify that fast read is 4 times faster on cache read"
21145
21146         # small read with fast read enabled
21147         $LCTL set_param -n llite.*.fast_read=1
21148         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21149                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21150                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21151         # small read with fast read disabled
21152         $LCTL set_param -n llite.*.fast_read=0
21153         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21154                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21155                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21156
21157         # verify that fast read is 4 times faster for cache read
21158         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21159                 error_not_in_vm "fast read was not 4 times faster: " \
21160                            "$t_fast vs $t_slow"
21161
21162         echo "Test 2: verify the performance between big and small read"
21163         $LCTL set_param -n llite.*.fast_read=1
21164
21165         # 1k non-cache read
21166         cancel_lru_locks osc
21167         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21168                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21169                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21170
21171         # 1M non-cache read
21172         cancel_lru_locks osc
21173         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21174                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21175                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21176
21177         # verify that big IO is not 4 times faster than small IO
21178         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21179                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21180
21181         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21182         rm -f $DIR/$tfile
21183 }
21184 run_test 248a "fast read verification"
21185
21186 test_248b() {
21187         # Default short_io_bytes=16384, try both smaller and larger sizes.
21188         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21189         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21190         echo "bs=53248 count=113 normal buffered write"
21191         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21192                 error "dd of initial data file failed"
21193         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21194
21195         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21196         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21197                 error "dd with sync normal writes failed"
21198         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21199
21200         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21201         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21202                 error "dd with sync small writes failed"
21203         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21204
21205         cancel_lru_locks osc
21206
21207         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21208         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21209         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21210         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21211                 iflag=direct || error "dd with O_DIRECT small read failed"
21212         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21213         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21214                 error "compare $TMP/$tfile.1 failed"
21215
21216         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21217         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21218
21219         # just to see what the maximum tunable value is, and test parsing
21220         echo "test invalid parameter 2MB"
21221         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21222                 error "too-large short_io_bytes allowed"
21223         echo "test maximum parameter 512KB"
21224         # if we can set a larger short_io_bytes, run test regardless of version
21225         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21226                 # older clients may not allow setting it this large, that's OK
21227                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21228                         skip "Need at least client version 2.13.50"
21229                 error "medium short_io_bytes failed"
21230         fi
21231         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21232         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21233
21234         echo "test large parameter 64KB"
21235         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21236         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21237
21238         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21239         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21240                 error "dd with sync large writes failed"
21241         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21242
21243         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21244         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21245         num=$((113 * 4096 / PAGE_SIZE))
21246         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21247         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21248                 error "dd with O_DIRECT large writes failed"
21249         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21250                 error "compare $DIR/$tfile.3 failed"
21251
21252         cancel_lru_locks osc
21253
21254         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21255         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21256                 error "dd with O_DIRECT large read failed"
21257         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21258                 error "compare $TMP/$tfile.2 failed"
21259
21260         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21261         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21262                 error "dd with O_DIRECT large read failed"
21263         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21264                 error "compare $TMP/$tfile.3 failed"
21265 }
21266 run_test 248b "test short_io read and write for both small and large sizes"
21267
21268 test_249() { # LU-7890
21269         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21270                 skip "Need at least version 2.8.54"
21271
21272         rm -f $DIR/$tfile
21273         $LFS setstripe -c 1 $DIR/$tfile
21274         # Offset 2T == 4k * 512M
21275         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21276                 error "dd to 2T offset failed"
21277 }
21278 run_test 249 "Write above 2T file size"
21279
21280 test_250() {
21281         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21282          && skip "no 16TB file size limit on ZFS"
21283
21284         $LFS setstripe -c 1 $DIR/$tfile
21285         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21286         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21287         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21288         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21289                 conv=notrunc,fsync && error "append succeeded"
21290         return 0
21291 }
21292 run_test 250 "Write above 16T limit"
21293
21294 test_251() {
21295         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21296
21297         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21298         #Skip once - writing the first stripe will succeed
21299         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21300         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21301                 error "short write happened"
21302
21303         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21304         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21305                 error "short read happened"
21306
21307         rm -f $DIR/$tfile
21308 }
21309 run_test 251 "Handling short read and write correctly"
21310
21311 test_252() {
21312         remote_mds_nodsh && skip "remote MDS with nodsh"
21313         remote_ost_nodsh && skip "remote OST with nodsh"
21314         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21315                 skip_env "ldiskfs only test"
21316         fi
21317
21318         local tgt
21319         local dev
21320         local out
21321         local uuid
21322         local num
21323         local gen
21324
21325         # check lr_reader on OST0000
21326         tgt=ost1
21327         dev=$(facet_device $tgt)
21328         out=$(do_facet $tgt $LR_READER $dev)
21329         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21330         echo "$out"
21331         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21332         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21333                 error "Invalid uuid returned by $LR_READER on target $tgt"
21334         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21335
21336         # check lr_reader -c on MDT0000
21337         tgt=mds1
21338         dev=$(facet_device $tgt)
21339         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21340                 skip "$LR_READER does not support additional options"
21341         fi
21342         out=$(do_facet $tgt $LR_READER -c $dev)
21343         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21344         echo "$out"
21345         num=$(echo "$out" | grep -c "mdtlov")
21346         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21347                 error "Invalid number of mdtlov clients returned by $LR_READER"
21348         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21349
21350         # check lr_reader -cr on MDT0000
21351         out=$(do_facet $tgt $LR_READER -cr $dev)
21352         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21353         echo "$out"
21354         echo "$out" | grep -q "^reply_data:$" ||
21355                 error "$LR_READER should have returned 'reply_data' section"
21356         num=$(echo "$out" | grep -c "client_generation")
21357         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21358 }
21359 run_test 252 "check lr_reader tool"
21360
21361 test_253() {
21362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21363         remote_mds_nodsh && skip "remote MDS with nodsh"
21364         remote_mgs_nodsh && skip "remote MGS with nodsh"
21365
21366         local ostidx=0
21367         local rc=0
21368         local ost_name=$(ostname_from_index $ostidx)
21369
21370         # on the mdt's osc
21371         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21372         do_facet $SINGLEMDS $LCTL get_param -n \
21373                 osp.$mdtosc_proc1.reserved_mb_high ||
21374                 skip  "remote MDS does not support reserved_mb_high"
21375
21376         rm -rf $DIR/$tdir
21377         wait_mds_ost_sync
21378         wait_delete_completed
21379         mkdir $DIR/$tdir
21380
21381         pool_add $TESTNAME || error "Pool creation failed"
21382         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21383
21384         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21385                 error "Setstripe failed"
21386
21387         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21388
21389         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21390                     grep "watermarks")
21391         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21392
21393         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21394                         osp.$mdtosc_proc1.prealloc_status)
21395         echo "prealloc_status $oa_status"
21396
21397         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21398                 error "File creation should fail"
21399
21400         #object allocation was stopped, but we still able to append files
21401         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21402                 oflag=append || error "Append failed"
21403
21404         rm -f $DIR/$tdir/$tfile.0
21405
21406         # For this test, we want to delete the files we created to go out of
21407         # space but leave the watermark, so we remain nearly out of space
21408         ost_watermarks_enospc_delete_files $tfile $ostidx
21409
21410         wait_delete_completed
21411
21412         sleep_maxage
21413
21414         for i in $(seq 10 12); do
21415                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21416                         2>/dev/null || error "File creation failed after rm"
21417         done
21418
21419         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21420                         osp.$mdtosc_proc1.prealloc_status)
21421         echo "prealloc_status $oa_status"
21422
21423         if (( oa_status != 0 )); then
21424                 error "Object allocation still disable after rm"
21425         fi
21426 }
21427 run_test 253 "Check object allocation limit"
21428
21429 test_254() {
21430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21431         remote_mds_nodsh && skip "remote MDS with nodsh"
21432
21433         local mdt=$(facet_svc $SINGLEMDS)
21434
21435         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21436                 skip "MDS does not support changelog_size"
21437
21438         local cl_user
21439
21440         changelog_register || error "changelog_register failed"
21441
21442         changelog_clear 0 || error "changelog_clear failed"
21443
21444         local size1=$(do_facet $SINGLEMDS \
21445                       $LCTL get_param -n mdd.$mdt.changelog_size)
21446         echo "Changelog size $size1"
21447
21448         rm -rf $DIR/$tdir
21449         $LFS mkdir -i 0 $DIR/$tdir
21450         # change something
21451         mkdir -p $DIR/$tdir/pics/2008/zachy
21452         touch $DIR/$tdir/pics/2008/zachy/timestamp
21453         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21454         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21455         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21456         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21457         rm $DIR/$tdir/pics/desktop.jpg
21458
21459         local size2=$(do_facet $SINGLEMDS \
21460                       $LCTL get_param -n mdd.$mdt.changelog_size)
21461         echo "Changelog size after work $size2"
21462
21463         (( $size2 > $size1 )) ||
21464                 error "new Changelog size=$size2 less than old size=$size1"
21465 }
21466 run_test 254 "Check changelog size"
21467
21468 ladvise_no_type()
21469 {
21470         local type=$1
21471         local file=$2
21472
21473         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21474                 awk -F: '{print $2}' | grep $type > /dev/null
21475         if [ $? -ne 0 ]; then
21476                 return 0
21477         fi
21478         return 1
21479 }
21480
21481 ladvise_no_ioctl()
21482 {
21483         local file=$1
21484
21485         lfs ladvise -a willread $file > /dev/null 2>&1
21486         if [ $? -eq 0 ]; then
21487                 return 1
21488         fi
21489
21490         lfs ladvise -a willread $file 2>&1 |
21491                 grep "Inappropriate ioctl for device" > /dev/null
21492         if [ $? -eq 0 ]; then
21493                 return 0
21494         fi
21495         return 1
21496 }
21497
21498 percent() {
21499         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21500 }
21501
21502 # run a random read IO workload
21503 # usage: random_read_iops <filename> <filesize> <iosize>
21504 random_read_iops() {
21505         local file=$1
21506         local fsize=$2
21507         local iosize=${3:-4096}
21508
21509         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21510                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21511 }
21512
21513 drop_file_oss_cache() {
21514         local file="$1"
21515         local nodes="$2"
21516
21517         $LFS ladvise -a dontneed $file 2>/dev/null ||
21518                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21519 }
21520
21521 ladvise_willread_performance()
21522 {
21523         local repeat=10
21524         local average_origin=0
21525         local average_cache=0
21526         local average_ladvise=0
21527
21528         for ((i = 1; i <= $repeat; i++)); do
21529                 echo "Iter $i/$repeat: reading without willread hint"
21530                 cancel_lru_locks osc
21531                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21532                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21533                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21534                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21535
21536                 cancel_lru_locks osc
21537                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21538                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21539                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21540
21541                 cancel_lru_locks osc
21542                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21543                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21544                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21545                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21546                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21547         done
21548         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21549         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21550         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21551
21552         speedup_cache=$(percent $average_cache $average_origin)
21553         speedup_ladvise=$(percent $average_ladvise $average_origin)
21554
21555         echo "Average uncached read: $average_origin"
21556         echo "Average speedup with OSS cached read: " \
21557                 "$average_cache = +$speedup_cache%"
21558         echo "Average speedup with ladvise willread: " \
21559                 "$average_ladvise = +$speedup_ladvise%"
21560
21561         local lowest_speedup=20
21562         if (( ${average_cache%.*} < $lowest_speedup )); then
21563                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21564                      " got $average_cache%. Skipping ladvise willread check."
21565                 return 0
21566         fi
21567
21568         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21569         # it is still good to run until then to exercise 'ladvise willread'
21570         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21571                 [ "$ost1_FSTYPE" = "zfs" ] &&
21572                 echo "osd-zfs does not support dontneed or drop_caches" &&
21573                 return 0
21574
21575         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21576         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21577                 error_not_in_vm "Speedup with willread is less than " \
21578                         "$lowest_speedup%, got $average_ladvise%"
21579 }
21580
21581 test_255a() {
21582         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21583                 skip "lustre < 2.8.54 does not support ladvise "
21584         remote_ost_nodsh && skip "remote OST with nodsh"
21585
21586         stack_trap "rm -f $DIR/$tfile"
21587         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21588
21589         ladvise_no_type willread $DIR/$tfile &&
21590                 skip "willread ladvise is not supported"
21591
21592         ladvise_no_ioctl $DIR/$tfile &&
21593                 skip "ladvise ioctl is not supported"
21594
21595         local size_mb=100
21596         local size=$((size_mb * 1048576))
21597         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21598                 error "dd to $DIR/$tfile failed"
21599
21600         lfs ladvise -a willread $DIR/$tfile ||
21601                 error "Ladvise failed with no range argument"
21602
21603         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21604                 error "Ladvise failed with no -l or -e argument"
21605
21606         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21607                 error "Ladvise failed with only -e argument"
21608
21609         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21610                 error "Ladvise failed with only -l argument"
21611
21612         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21613                 error "End offset should not be smaller than start offset"
21614
21615         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21616                 error "End offset should not be equal to start offset"
21617
21618         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21619                 error "Ladvise failed with overflowing -s argument"
21620
21621         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21622                 error "Ladvise failed with overflowing -e argument"
21623
21624         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21625                 error "Ladvise failed with overflowing -l argument"
21626
21627         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21628                 error "Ladvise succeeded with conflicting -l and -e arguments"
21629
21630         echo "Synchronous ladvise should wait"
21631         local delay=4
21632 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21633         do_nodes $(comma_list $(osts_nodes)) \
21634                 $LCTL set_param fail_val=$delay fail_loc=0x237
21635
21636         local start_ts=$SECONDS
21637         lfs ladvise -a willread $DIR/$tfile ||
21638                 error "Ladvise failed with no range argument"
21639         local end_ts=$SECONDS
21640         local inteval_ts=$((end_ts - start_ts))
21641
21642         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21643                 error "Synchronous advice didn't wait reply"
21644         fi
21645
21646         echo "Asynchronous ladvise shouldn't wait"
21647         local start_ts=$SECONDS
21648         lfs ladvise -a willread -b $DIR/$tfile ||
21649                 error "Ladvise failed with no range argument"
21650         local end_ts=$SECONDS
21651         local inteval_ts=$((end_ts - start_ts))
21652
21653         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21654                 error "Asynchronous advice blocked"
21655         fi
21656
21657         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21658         ladvise_willread_performance
21659 }
21660 run_test 255a "check 'lfs ladvise -a willread'"
21661
21662 facet_meminfo() {
21663         local facet=$1
21664         local info=$2
21665
21666         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21667 }
21668
21669 test_255b() {
21670         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21671                 skip "lustre < 2.8.54 does not support ladvise "
21672         remote_ost_nodsh && skip "remote OST with nodsh"
21673
21674         stack_trap "rm -f $DIR/$tfile"
21675         lfs setstripe -c 1 -i 0 $DIR/$tfile
21676
21677         ladvise_no_type dontneed $DIR/$tfile &&
21678                 skip "dontneed ladvise is not supported"
21679
21680         ladvise_no_ioctl $DIR/$tfile &&
21681                 skip "ladvise ioctl is not supported"
21682
21683         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21684                 [ "$ost1_FSTYPE" = "zfs" ] &&
21685                 skip "zfs-osd does not support 'ladvise dontneed'"
21686
21687         local size_mb=100
21688         local size=$((size_mb * 1048576))
21689         # In order to prevent disturbance of other processes, only check 3/4
21690         # of the memory usage
21691         local kibibytes=$((size_mb * 1024 * 3 / 4))
21692
21693         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21694                 error "dd to $DIR/$tfile failed"
21695
21696         #force write to complete before dropping OST cache & checking memory
21697         sync
21698
21699         local total=$(facet_meminfo ost1 MemTotal)
21700         echo "Total memory: $total KiB"
21701
21702         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21703         local before_read=$(facet_meminfo ost1 Cached)
21704         echo "Cache used before read: $before_read KiB"
21705
21706         lfs ladvise -a willread $DIR/$tfile ||
21707                 error "Ladvise willread failed"
21708         local after_read=$(facet_meminfo ost1 Cached)
21709         echo "Cache used after read: $after_read KiB"
21710
21711         lfs ladvise -a dontneed $DIR/$tfile ||
21712                 error "Ladvise dontneed again failed"
21713         local no_read=$(facet_meminfo ost1 Cached)
21714         echo "Cache used after dontneed ladvise: $no_read KiB"
21715
21716         if [ $total -lt $((before_read + kibibytes)) ]; then
21717                 echo "Memory is too small, abort checking"
21718                 return 0
21719         fi
21720
21721         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21722                 error "Ladvise willread should use more memory" \
21723                         "than $kibibytes KiB"
21724         fi
21725
21726         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21727                 error "Ladvise dontneed should release more memory" \
21728                         "than $kibibytes KiB"
21729         fi
21730 }
21731 run_test 255b "check 'lfs ladvise -a dontneed'"
21732
21733 test_255c() {
21734         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21735                 skip "lustre < 2.10.50 does not support lockahead"
21736
21737         local ost1_imp=$(get_osc_import_name client ost1)
21738         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21739                          cut -d'.' -f2)
21740         local count
21741         local new_count
21742         local difference
21743         local i
21744         local rc
21745
21746         test_mkdir -p $DIR/$tdir
21747         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21748
21749         #test 10 returns only success/failure
21750         i=10
21751         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21752         rc=$?
21753         if [ $rc -eq 255 ]; then
21754                 error "Ladvise test${i} failed, ${rc}"
21755         fi
21756
21757         #test 11 counts lock enqueue requests, all others count new locks
21758         i=11
21759         count=$(do_facet ost1 \
21760                 $LCTL get_param -n ost.OSS.ost.stats)
21761         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21762
21763         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21764         rc=$?
21765         if [ $rc -eq 255 ]; then
21766                 error "Ladvise test${i} failed, ${rc}"
21767         fi
21768
21769         new_count=$(do_facet ost1 \
21770                 $LCTL get_param -n ost.OSS.ost.stats)
21771         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21772                    awk '{ print $2 }')
21773
21774         difference="$((new_count - count))"
21775         if [ $difference -ne $rc ]; then
21776                 error "Ladvise test${i}, bad enqueue count, returned " \
21777                       "${rc}, actual ${difference}"
21778         fi
21779
21780         for i in $(seq 12 21); do
21781                 # If we do not do this, we run the risk of having too many
21782                 # locks and starting lock cancellation while we are checking
21783                 # lock counts.
21784                 cancel_lru_locks osc
21785
21786                 count=$($LCTL get_param -n \
21787                        ldlm.namespaces.$imp_name.lock_unused_count)
21788
21789                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21790                 rc=$?
21791                 if [ $rc -eq 255 ]; then
21792                         error "Ladvise test ${i} failed, ${rc}"
21793                 fi
21794
21795                 new_count=$($LCTL get_param -n \
21796                        ldlm.namespaces.$imp_name.lock_unused_count)
21797                 difference="$((new_count - count))"
21798
21799                 # Test 15 output is divided by 100 to map down to valid return
21800                 if [ $i -eq 15 ]; then
21801                         rc="$((rc * 100))"
21802                 fi
21803
21804                 if [ $difference -ne $rc ]; then
21805                         error "Ladvise test ${i}, bad lock count, returned " \
21806                               "${rc}, actual ${difference}"
21807                 fi
21808         done
21809
21810         #test 22 returns only success/failure
21811         i=22
21812         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21813         rc=$?
21814         if [ $rc -eq 255 ]; then
21815                 error "Ladvise test${i} failed, ${rc}"
21816         fi
21817 }
21818 run_test 255c "suite of ladvise lockahead tests"
21819
21820 test_256() {
21821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21822         remote_mds_nodsh && skip "remote MDS with nodsh"
21823         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21824         changelog_users $SINGLEMDS | grep "^cl" &&
21825                 skip "active changelog user"
21826
21827         local cl_user
21828         local cat_sl
21829         local mdt_dev
21830
21831         mdt_dev=$(facet_device $SINGLEMDS)
21832         echo $mdt_dev
21833
21834         changelog_register || error "changelog_register failed"
21835
21836         rm -rf $DIR/$tdir
21837         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21838
21839         changelog_clear 0 || error "changelog_clear failed"
21840
21841         # change something
21842         touch $DIR/$tdir/{1..10}
21843
21844         # stop the MDT
21845         stop $SINGLEMDS || error "Fail to stop MDT"
21846
21847         # remount the MDT
21848         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21849                 error "Fail to start MDT"
21850
21851         #after mount new plainllog is used
21852         touch $DIR/$tdir/{11..19}
21853         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21854         stack_trap "rm -f $tmpfile"
21855         cat_sl=$(do_facet $SINGLEMDS "sync; \
21856                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21857                  llog_reader $tmpfile | grep -c type=1064553b")
21858         do_facet $SINGLEMDS llog_reader $tmpfile
21859
21860         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21861
21862         changelog_clear 0 || error "changelog_clear failed"
21863
21864         cat_sl=$(do_facet $SINGLEMDS "sync; \
21865                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21866                  llog_reader $tmpfile | grep -c type=1064553b")
21867
21868         if (( cat_sl == 2 )); then
21869                 error "Empty plain llog was not deleted from changelog catalog"
21870         elif (( cat_sl != 1 )); then
21871                 error "Active plain llog shouldn't be deleted from catalog"
21872         fi
21873 }
21874 run_test 256 "Check llog delete for empty and not full state"
21875
21876 test_257() {
21877         remote_mds_nodsh && skip "remote MDS with nodsh"
21878         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21879                 skip "Need MDS version at least 2.8.55"
21880
21881         test_mkdir $DIR/$tdir
21882
21883         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21884                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21885         stat $DIR/$tdir
21886
21887 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21888         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21889         local facet=mds$((mdtidx + 1))
21890         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21891         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21892
21893         stop $facet || error "stop MDS failed"
21894         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21895                 error "start MDS fail"
21896         wait_recovery_complete $facet
21897 }
21898 run_test 257 "xattr locks are not lost"
21899
21900 # Verify we take the i_mutex when security requires it
21901 test_258a() {
21902 #define OBD_FAIL_IMUTEX_SEC 0x141c
21903         $LCTL set_param fail_loc=0x141c
21904         touch $DIR/$tfile
21905         chmod u+s $DIR/$tfile
21906         chmod a+rwx $DIR/$tfile
21907         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21908         RC=$?
21909         if [ $RC -ne 0 ]; then
21910                 error "error, failed to take i_mutex, rc=$?"
21911         fi
21912         rm -f $DIR/$tfile
21913 }
21914 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21915
21916 # Verify we do NOT take the i_mutex in the normal case
21917 test_258b() {
21918 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21919         $LCTL set_param fail_loc=0x141d
21920         touch $DIR/$tfile
21921         chmod a+rwx $DIR
21922         chmod a+rw $DIR/$tfile
21923         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21924         RC=$?
21925         if [ $RC -ne 0 ]; then
21926                 error "error, took i_mutex unnecessarily, rc=$?"
21927         fi
21928         rm -f $DIR/$tfile
21929
21930 }
21931 run_test 258b "verify i_mutex security behavior"
21932
21933 test_259() {
21934         local file=$DIR/$tfile
21935         local before
21936         local after
21937
21938         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21939
21940         stack_trap "rm -f $file" EXIT
21941
21942         wait_delete_completed
21943         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21944         echo "before: $before"
21945
21946         $LFS setstripe -i 0 -c 1 $file
21947         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21948         sync_all_data
21949         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21950         echo "after write: $after"
21951
21952 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21953         do_facet ost1 $LCTL set_param fail_loc=0x2301
21954         $TRUNCATE $file 0
21955         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21956         echo "after truncate: $after"
21957
21958         stop ost1
21959         do_facet ost1 $LCTL set_param fail_loc=0
21960         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21961         sleep 2
21962         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21963         echo "after restart: $after"
21964         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21965                 error "missing truncate?"
21966
21967         return 0
21968 }
21969 run_test 259 "crash at delayed truncate"
21970
21971 test_260() {
21972 #define OBD_FAIL_MDC_CLOSE               0x806
21973         $LCTL set_param fail_loc=0x80000806
21974         touch $DIR/$tfile
21975
21976 }
21977 run_test 260 "Check mdc_close fail"
21978
21979 ### Data-on-MDT sanity tests ###
21980 test_270a() {
21981         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21982                 skip "Need MDS version at least 2.10.55 for DoM"
21983
21984         # create DoM file
21985         local dom=$DIR/$tdir/dom_file
21986         local tmp=$DIR/$tdir/tmp_file
21987
21988         mkdir_on_mdt0 $DIR/$tdir
21989
21990         # basic checks for DoM component creation
21991         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21992                 error "Can set MDT layout to non-first entry"
21993
21994         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21995                 error "Can define multiple entries as MDT layout"
21996
21997         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21998
21999         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22000         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22001         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22002
22003         local mdtidx=$($LFS getstripe -m $dom)
22004         local mdtname=MDT$(printf %04x $mdtidx)
22005         local facet=mds$((mdtidx + 1))
22006         local space_check=1
22007
22008         # Skip free space checks with ZFS
22009         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22010
22011         # write
22012         sync
22013         local size_tmp=$((65536 * 3))
22014         local mdtfree1=$(do_facet $facet \
22015                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22016
22017         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22018         # check also direct IO along write
22019         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22020         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22021         sync
22022         cmp $tmp $dom || error "file data is different"
22023         [ $(stat -c%s $dom) == $size_tmp ] ||
22024                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22025         if [ $space_check == 1 ]; then
22026                 local mdtfree2=$(do_facet $facet \
22027                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22028
22029                 # increase in usage from by $size_tmp
22030                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22031                         error "MDT free space wrong after write: " \
22032                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22033         fi
22034
22035         # truncate
22036         local size_dom=10000
22037
22038         $TRUNCATE $dom $size_dom
22039         [ $(stat -c%s $dom) == $size_dom ] ||
22040                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22041         if [ $space_check == 1 ]; then
22042                 mdtfree1=$(do_facet $facet \
22043                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22044                 # decrease in usage from $size_tmp to new $size_dom
22045                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22046                   $(((size_tmp - size_dom) / 1024)) ] ||
22047                         error "MDT free space is wrong after truncate: " \
22048                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22049         fi
22050
22051         # append
22052         cat $tmp >> $dom
22053         sync
22054         size_dom=$((size_dom + size_tmp))
22055         [ $(stat -c%s $dom) == $size_dom ] ||
22056                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22057         if [ $space_check == 1 ]; then
22058                 mdtfree2=$(do_facet $facet \
22059                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22060                 # increase in usage by $size_tmp from previous
22061                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22062                         error "MDT free space is wrong after append: " \
22063                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22064         fi
22065
22066         # delete
22067         rm $dom
22068         if [ $space_check == 1 ]; then
22069                 mdtfree1=$(do_facet $facet \
22070                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22071                 # decrease in usage by $size_dom from previous
22072                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22073                         error "MDT free space is wrong after removal: " \
22074                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22075         fi
22076
22077         # combined striping
22078         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22079                 error "Can't create DoM + OST striping"
22080
22081         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22082         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22083         # check also direct IO along write
22084         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22085         sync
22086         cmp $tmp $dom || error "file data is different"
22087         [ $(stat -c%s $dom) == $size_tmp ] ||
22088                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22089         rm $dom $tmp
22090
22091         return 0
22092 }
22093 run_test 270a "DoM: basic functionality tests"
22094
22095 test_270b() {
22096         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22097                 skip "Need MDS version at least 2.10.55"
22098
22099         local dom=$DIR/$tdir/dom_file
22100         local max_size=1048576
22101
22102         mkdir -p $DIR/$tdir
22103         $LFS setstripe -E $max_size -L mdt $dom
22104
22105         # truncate over the limit
22106         $TRUNCATE $dom $(($max_size + 1)) &&
22107                 error "successful truncate over the maximum size"
22108         # write over the limit
22109         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22110                 error "successful write over the maximum size"
22111         # append over the limit
22112         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22113         echo "12345" >> $dom && error "successful append over the maximum size"
22114         rm $dom
22115
22116         return 0
22117 }
22118 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22119
22120 test_270c() {
22121         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22122                 skip "Need MDS version at least 2.10.55"
22123
22124         mkdir -p $DIR/$tdir
22125         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22126
22127         # check files inherit DoM EA
22128         touch $DIR/$tdir/first
22129         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22130                 error "bad pattern"
22131         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22132                 error "bad stripe count"
22133         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22134                 error "bad stripe size"
22135
22136         # check directory inherits DoM EA and uses it as default
22137         mkdir $DIR/$tdir/subdir
22138         touch $DIR/$tdir/subdir/second
22139         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22140                 error "bad pattern in sub-directory"
22141         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22142                 error "bad stripe count in sub-directory"
22143         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22144                 error "bad stripe size in sub-directory"
22145         return 0
22146 }
22147 run_test 270c "DoM: DoM EA inheritance tests"
22148
22149 test_270d() {
22150         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22151                 skip "Need MDS version at least 2.10.55"
22152
22153         mkdir -p $DIR/$tdir
22154         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22155
22156         # inherit default DoM striping
22157         mkdir $DIR/$tdir/subdir
22158         touch $DIR/$tdir/subdir/f1
22159
22160         # change default directory striping
22161         $LFS setstripe -c 1 $DIR/$tdir/subdir
22162         touch $DIR/$tdir/subdir/f2
22163         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22164                 error "wrong default striping in file 2"
22165         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22166                 error "bad pattern in file 2"
22167         return 0
22168 }
22169 run_test 270d "DoM: change striping from DoM to RAID0"
22170
22171 test_270e() {
22172         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22173                 skip "Need MDS version at least 2.10.55"
22174
22175         mkdir -p $DIR/$tdir/dom
22176         mkdir -p $DIR/$tdir/norm
22177         DOMFILES=20
22178         NORMFILES=10
22179         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22180         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22181
22182         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22183         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22184
22185         # find DoM files by layout
22186         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22187         [ $NUM -eq  $DOMFILES ] ||
22188                 error "lfs find -L: found $NUM, expected $DOMFILES"
22189         echo "Test 1: lfs find 20 DOM files by layout: OK"
22190
22191         # there should be 1 dir with default DOM striping
22192         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22193         [ $NUM -eq  1 ] ||
22194                 error "lfs find -L: found $NUM, expected 1 dir"
22195         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22196
22197         # find DoM files by stripe size
22198         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22199         [ $NUM -eq  $DOMFILES ] ||
22200                 error "lfs find -S: found $NUM, expected $DOMFILES"
22201         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22202
22203         # find files by stripe offset except DoM files
22204         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22205         [ $NUM -eq  $NORMFILES ] ||
22206                 error "lfs find -i: found $NUM, expected $NORMFILES"
22207         echo "Test 5: lfs find no DOM files by stripe index: OK"
22208         return 0
22209 }
22210 run_test 270e "DoM: lfs find with DoM files test"
22211
22212 test_270f() {
22213         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22214                 skip "Need MDS version at least 2.10.55"
22215
22216         local mdtname=${FSNAME}-MDT0000-mdtlov
22217         local dom=$DIR/$tdir/dom_file
22218         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22219                                                 lod.$mdtname.dom_stripesize)
22220         local dom_limit=131072
22221
22222         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22223         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22224                                                 lod.$mdtname.dom_stripesize)
22225         [ ${dom_limit} -eq ${dom_current} ] ||
22226                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22227
22228         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22229         $LFS setstripe -d $DIR/$tdir
22230         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22231                 error "Can't set directory default striping"
22232
22233         # exceed maximum stripe size
22234         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22235                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22236         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22237                 error "Able to create DoM component size more than LOD limit"
22238
22239         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22240         dom_current=$(do_facet mds1 $LCTL get_param -n \
22241                                                 lod.$mdtname.dom_stripesize)
22242         [ 0 -eq ${dom_current} ] ||
22243                 error "Can't set zero DoM stripe limit"
22244         rm $dom
22245
22246         # attempt to create DoM file on server with disabled DoM should
22247         # remove DoM entry from layout and be succeed
22248         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22249                 error "Can't create DoM file (DoM is disabled)"
22250         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22251                 error "File has DoM component while DoM is disabled"
22252         rm $dom
22253
22254         # attempt to create DoM file with only DoM stripe should return error
22255         $LFS setstripe -E $dom_limit -L mdt $dom &&
22256                 error "Able to create DoM-only file while DoM is disabled"
22257
22258         # too low values to be aligned with smallest stripe size 64K
22259         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22260         dom_current=$(do_facet mds1 $LCTL get_param -n \
22261                                                 lod.$mdtname.dom_stripesize)
22262         [ 30000 -eq ${dom_current} ] &&
22263                 error "Can set too small DoM stripe limit"
22264
22265         # 64K is a minimal stripe size in Lustre, expect limit of that size
22266         [ 65536 -eq ${dom_current} ] ||
22267                 error "Limit is not set to 64K but ${dom_current}"
22268
22269         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22270         dom_current=$(do_facet mds1 $LCTL get_param -n \
22271                                                 lod.$mdtname.dom_stripesize)
22272         echo $dom_current
22273         [ 2147483648 -eq ${dom_current} ] &&
22274                 error "Can set too large DoM stripe limit"
22275
22276         do_facet mds1 $LCTL set_param -n \
22277                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22278         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22279                 error "Can't create DoM component size after limit change"
22280         do_facet mds1 $LCTL set_param -n \
22281                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22282         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22283                 error "Can't create DoM file after limit decrease"
22284         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22285                 error "Can create big DoM component after limit decrease"
22286         touch ${dom}_def ||
22287                 error "Can't create file with old default layout"
22288
22289         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22290         return 0
22291 }
22292 run_test 270f "DoM: maximum DoM stripe size checks"
22293
22294 test_270g() {
22295         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22296                 skip "Need MDS version at least 2.13.52"
22297         local dom=$DIR/$tdir/$tfile
22298
22299         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22300         local lodname=${FSNAME}-MDT0000-mdtlov
22301
22302         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22303         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22304         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22305         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22306
22307         local dom_limit=1024
22308         local dom_threshold="50%"
22309
22310         $LFS setstripe -d $DIR/$tdir
22311         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22312                 error "Can't set directory default striping"
22313
22314         do_facet mds1 $LCTL set_param -n \
22315                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22316         # set 0 threshold and create DOM file to change tunable stripesize
22317         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22318         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22319                 error "Failed to create $dom file"
22320         # now tunable dom_cur_stripesize should reach maximum
22321         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22322                                         lod.${lodname}.dom_stripesize_cur_kb)
22323         [[ $dom_current == $dom_limit ]] ||
22324                 error "Current DOM stripesize is not maximum"
22325         rm $dom
22326
22327         # set threshold for further tests
22328         do_facet mds1 $LCTL set_param -n \
22329                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22330         echo "DOM threshold is $dom_threshold free space"
22331         local dom_def
22332         local dom_set
22333         # Spoof bfree to exceed threshold
22334         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22335         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22336         for spfree in 40 20 0 15 30 55; do
22337                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22338                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22339                         error "Failed to create $dom file"
22340                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22341                                         lod.${lodname}.dom_stripesize_cur_kb)
22342                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22343                 [[ $dom_def != $dom_current ]] ||
22344                         error "Default stripe size was not changed"
22345                 if (( spfree > 0 )) ; then
22346                         dom_set=$($LFS getstripe -S $dom)
22347                         (( dom_set == dom_def * 1024 )) ||
22348                                 error "DOM component size is still old"
22349                 else
22350                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22351                                 error "DoM component is set with no free space"
22352                 fi
22353                 rm $dom
22354                 dom_current=$dom_def
22355         done
22356 }
22357 run_test 270g "DoM: default DoM stripe size depends on free space"
22358
22359 test_270h() {
22360         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22361                 skip "Need MDS version at least 2.13.53"
22362
22363         local mdtname=${FSNAME}-MDT0000-mdtlov
22364         local dom=$DIR/$tdir/$tfile
22365         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22366
22367         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22368         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22369
22370         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22371         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22372                 error "can't create OST file"
22373         # mirrored file with DOM entry in the second mirror
22374         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22375                 error "can't create mirror with DoM component"
22376
22377         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22378
22379         # DOM component in the middle and has other enries in the same mirror,
22380         # should succeed but lost DoM component
22381         $LFS setstripe --copy=${dom}_1 $dom ||
22382                 error "Can't create file from OST|DOM mirror layout"
22383         # check new file has no DoM layout after all
22384         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22385                 error "File has DoM component while DoM is disabled"
22386 }
22387 run_test 270h "DoM: DoM stripe removal when disabled on server"
22388
22389 test_270i() {
22390         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22391                 skip "Need MDS version at least 2.14.54"
22392
22393         mkdir $DIR/$tdir
22394         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22395                 error "setstripe should fail" || true
22396 }
22397 run_test 270i "DoM: setting invalid DoM striping should fail"
22398
22399 test_271a() {
22400         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22401                 skip "Need MDS version at least 2.10.55"
22402
22403         local dom=$DIR/$tdir/dom
22404
22405         mkdir -p $DIR/$tdir
22406
22407         $LFS setstripe -E 1024K -L mdt $dom
22408
22409         lctl set_param -n mdc.*.stats=clear
22410         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22411         cat $dom > /dev/null
22412         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22413         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22414         ls $dom
22415         rm -f $dom
22416 }
22417 run_test 271a "DoM: data is cached for read after write"
22418
22419 test_271b() {
22420         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22421                 skip "Need MDS version at least 2.10.55"
22422
22423         local dom=$DIR/$tdir/dom
22424
22425         mkdir -p $DIR/$tdir
22426
22427         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22428
22429         lctl set_param -n mdc.*.stats=clear
22430         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22431         cancel_lru_locks mdc
22432         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22433         # second stat to check size is cached on client
22434         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22435         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22436         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22437         rm -f $dom
22438 }
22439 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22440
22441 test_271ba() {
22442         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22443                 skip "Need MDS version at least 2.10.55"
22444
22445         local dom=$DIR/$tdir/dom
22446
22447         mkdir -p $DIR/$tdir
22448
22449         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22450
22451         lctl set_param -n mdc.*.stats=clear
22452         lctl set_param -n osc.*.stats=clear
22453         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22454         cancel_lru_locks mdc
22455         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22456         # second stat to check size is cached on client
22457         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22458         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22459         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22460         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22461         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22462         rm -f $dom
22463 }
22464 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22465
22466
22467 get_mdc_stats() {
22468         local mdtidx=$1
22469         local param=$2
22470         local mdt=MDT$(printf %04x $mdtidx)
22471
22472         if [ -z $param ]; then
22473                 lctl get_param -n mdc.*$mdt*.stats
22474         else
22475                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22476         fi
22477 }
22478
22479 test_271c() {
22480         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22481                 skip "Need MDS version at least 2.10.55"
22482
22483         local dom=$DIR/$tdir/dom
22484
22485         mkdir -p $DIR/$tdir
22486
22487         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22488
22489         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22490         local facet=mds$((mdtidx + 1))
22491
22492         cancel_lru_locks mdc
22493         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22494         createmany -o $dom 1000
22495         lctl set_param -n mdc.*.stats=clear
22496         smalliomany -w $dom 1000 200
22497         get_mdc_stats $mdtidx
22498         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22499         # Each file has 1 open, 1 IO enqueues, total 2000
22500         # but now we have also +1 getxattr for security.capability, total 3000
22501         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22502         unlinkmany $dom 1000
22503
22504         cancel_lru_locks mdc
22505         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22506         createmany -o $dom 1000
22507         lctl set_param -n mdc.*.stats=clear
22508         smalliomany -w $dom 1000 200
22509         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22510         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22511         # for OPEN and IO lock.
22512         [ $((enq - enq_2)) -ge 1000 ] ||
22513                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22514         unlinkmany $dom 1000
22515         return 0
22516 }
22517 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22518
22519 cleanup_271def_tests() {
22520         trap 0
22521         rm -f $1
22522 }
22523
22524 test_271d() {
22525         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22526                 skip "Need MDS version at least 2.10.57"
22527
22528         local dom=$DIR/$tdir/dom
22529         local tmp=$TMP/$tfile
22530         trap "cleanup_271def_tests $tmp" EXIT
22531
22532         mkdir -p $DIR/$tdir
22533
22534         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22535
22536         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22537
22538         cancel_lru_locks mdc
22539         dd if=/dev/urandom of=$tmp bs=1000 count=1
22540         dd if=$tmp of=$dom bs=1000 count=1
22541         cancel_lru_locks mdc
22542
22543         cat /etc/hosts >> $tmp
22544         lctl set_param -n mdc.*.stats=clear
22545
22546         # append data to the same file it should update local page
22547         echo "Append to the same page"
22548         cat /etc/hosts >> $dom
22549         local num=$(get_mdc_stats $mdtidx ost_read)
22550         local ra=$(get_mdc_stats $mdtidx req_active)
22551         local rw=$(get_mdc_stats $mdtidx req_waittime)
22552
22553         [ -z $num ] || error "$num READ RPC occured"
22554         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22555         echo "... DONE"
22556
22557         # compare content
22558         cmp $tmp $dom || error "file miscompare"
22559
22560         cancel_lru_locks mdc
22561         lctl set_param -n mdc.*.stats=clear
22562
22563         echo "Open and read file"
22564         cat $dom > /dev/null
22565         local num=$(get_mdc_stats $mdtidx ost_read)
22566         local ra=$(get_mdc_stats $mdtidx req_active)
22567         local rw=$(get_mdc_stats $mdtidx req_waittime)
22568
22569         [ -z $num ] || error "$num READ RPC occured"
22570         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22571         echo "... DONE"
22572
22573         # compare content
22574         cmp $tmp $dom || error "file miscompare"
22575
22576         return 0
22577 }
22578 run_test 271d "DoM: read on open (1K file in reply buffer)"
22579
22580 test_271f() {
22581         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22582                 skip "Need MDS version at least 2.10.57"
22583
22584         local dom=$DIR/$tdir/dom
22585         local tmp=$TMP/$tfile
22586         trap "cleanup_271def_tests $tmp" EXIT
22587
22588         mkdir -p $DIR/$tdir
22589
22590         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22591
22592         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22593
22594         cancel_lru_locks mdc
22595         dd if=/dev/urandom of=$tmp bs=265000 count=1
22596         dd if=$tmp of=$dom bs=265000 count=1
22597         cancel_lru_locks mdc
22598         cat /etc/hosts >> $tmp
22599         lctl set_param -n mdc.*.stats=clear
22600
22601         echo "Append to the same page"
22602         cat /etc/hosts >> $dom
22603         local num=$(get_mdc_stats $mdtidx ost_read)
22604         local ra=$(get_mdc_stats $mdtidx req_active)
22605         local rw=$(get_mdc_stats $mdtidx req_waittime)
22606
22607         [ -z $num ] || error "$num READ RPC occured"
22608         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22609         echo "... DONE"
22610
22611         # compare content
22612         cmp $tmp $dom || error "file miscompare"
22613
22614         cancel_lru_locks mdc
22615         lctl set_param -n mdc.*.stats=clear
22616
22617         echo "Open and read file"
22618         cat $dom > /dev/null
22619         local num=$(get_mdc_stats $mdtidx ost_read)
22620         local ra=$(get_mdc_stats $mdtidx req_active)
22621         local rw=$(get_mdc_stats $mdtidx req_waittime)
22622
22623         [ -z $num ] && num=0
22624         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22625         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22626         echo "... DONE"
22627
22628         # compare content
22629         cmp $tmp $dom || error "file miscompare"
22630
22631         return 0
22632 }
22633 run_test 271f "DoM: read on open (200K file and read tail)"
22634
22635 test_271g() {
22636         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22637                 skip "Skipping due to old client or server version"
22638
22639         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22640         # to get layout
22641         $CHECKSTAT -t file $DIR1/$tfile
22642
22643         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22644         MULTIOP_PID=$!
22645         sleep 1
22646         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22647         $LCTL set_param fail_loc=0x80000314
22648         rm $DIR1/$tfile || error "Unlink fails"
22649         RC=$?
22650         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22651         [ $RC -eq 0 ] || error "Failed write to stale object"
22652 }
22653 run_test 271g "Discard DoM data vs client flush race"
22654
22655 test_272a() {
22656         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22657                 skip "Need MDS version at least 2.11.50"
22658
22659         local dom=$DIR/$tdir/dom
22660         mkdir -p $DIR/$tdir
22661
22662         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22663         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22664                 error "failed to write data into $dom"
22665         local old_md5=$(md5sum $dom)
22666
22667         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22668                 error "failed to migrate to the same DoM component"
22669
22670         local new_md5=$(md5sum $dom)
22671
22672         [ "$old_md5" == "$new_md5" ] ||
22673                 error "md5sum differ: $old_md5, $new_md5"
22674
22675         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22676                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22677 }
22678 run_test 272a "DoM migration: new layout with the same DOM component"
22679
22680 test_272b() {
22681         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22682                 skip "Need MDS version at least 2.11.50"
22683
22684         local dom=$DIR/$tdir/dom
22685         mkdir -p $DIR/$tdir
22686         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22687
22688         local mdtidx=$($LFS getstripe -m $dom)
22689         local mdtname=MDT$(printf %04x $mdtidx)
22690         local facet=mds$((mdtidx + 1))
22691
22692         local mdtfree1=$(do_facet $facet \
22693                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22694         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22695                 error "failed to write data into $dom"
22696         local old_md5=$(md5sum $dom)
22697         cancel_lru_locks mdc
22698         local mdtfree1=$(do_facet $facet \
22699                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22700
22701         $LFS migrate -c2 $dom ||
22702                 error "failed to migrate to the new composite layout"
22703         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22704                 error "MDT stripe was not removed"
22705
22706         cancel_lru_locks mdc
22707         local new_md5=$(md5sum $dom)
22708         [ "$old_md5" == "$new_md5" ] ||
22709                 error "$old_md5 != $new_md5"
22710
22711         # Skip free space checks with ZFS
22712         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22713                 local mdtfree2=$(do_facet $facet \
22714                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22715                 [ $mdtfree2 -gt $mdtfree1 ] ||
22716                         error "MDT space is not freed after migration"
22717         fi
22718         return 0
22719 }
22720 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22721
22722 test_272c() {
22723         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22724                 skip "Need MDS version at least 2.11.50"
22725
22726         local dom=$DIR/$tdir/$tfile
22727         mkdir -p $DIR/$tdir
22728         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22729
22730         local mdtidx=$($LFS getstripe -m $dom)
22731         local mdtname=MDT$(printf %04x $mdtidx)
22732         local facet=mds$((mdtidx + 1))
22733
22734         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22735                 error "failed to write data into $dom"
22736         local old_md5=$(md5sum $dom)
22737         cancel_lru_locks mdc
22738         local mdtfree1=$(do_facet $facet \
22739                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22740
22741         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22742                 error "failed to migrate to the new composite layout"
22743         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22744                 error "MDT stripe was not removed"
22745
22746         cancel_lru_locks mdc
22747         local new_md5=$(md5sum $dom)
22748         [ "$old_md5" == "$new_md5" ] ||
22749                 error "$old_md5 != $new_md5"
22750
22751         # Skip free space checks with ZFS
22752         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22753                 local mdtfree2=$(do_facet $facet \
22754                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22755                 [ $mdtfree2 -gt $mdtfree1 ] ||
22756                         error "MDS space is not freed after migration"
22757         fi
22758         return 0
22759 }
22760 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22761
22762 test_272d() {
22763         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22764                 skip "Need MDS version at least 2.12.55"
22765
22766         local dom=$DIR/$tdir/$tfile
22767         mkdir -p $DIR/$tdir
22768         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22769
22770         local mdtidx=$($LFS getstripe -m $dom)
22771         local mdtname=MDT$(printf %04x $mdtidx)
22772         local facet=mds$((mdtidx + 1))
22773
22774         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22775                 error "failed to write data into $dom"
22776         local old_md5=$(md5sum $dom)
22777         cancel_lru_locks mdc
22778         local mdtfree1=$(do_facet $facet \
22779                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22780
22781         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22782                 error "failed mirroring to the new composite layout"
22783         $LFS mirror resync $dom ||
22784                 error "failed mirror resync"
22785         $LFS mirror split --mirror-id 1 -d $dom ||
22786                 error "failed mirror split"
22787
22788         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22789                 error "MDT stripe was not removed"
22790
22791         cancel_lru_locks mdc
22792         local new_md5=$(md5sum $dom)
22793         [ "$old_md5" == "$new_md5" ] ||
22794                 error "$old_md5 != $new_md5"
22795
22796         # Skip free space checks with ZFS
22797         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22798                 local mdtfree2=$(do_facet $facet \
22799                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22800                 [ $mdtfree2 -gt $mdtfree1 ] ||
22801                         error "MDS space is not freed after DOM mirror deletion"
22802         fi
22803         return 0
22804 }
22805 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22806
22807 test_272e() {
22808         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22809                 skip "Need MDS version at least 2.12.55"
22810
22811         local dom=$DIR/$tdir/$tfile
22812         mkdir -p $DIR/$tdir
22813         $LFS setstripe -c 2 $dom
22814
22815         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22816                 error "failed to write data into $dom"
22817         local old_md5=$(md5sum $dom)
22818         cancel_lru_locks
22819
22820         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22821                 error "failed mirroring to the DOM layout"
22822         $LFS mirror resync $dom ||
22823                 error "failed mirror resync"
22824         $LFS mirror split --mirror-id 1 -d $dom ||
22825                 error "failed mirror split"
22826
22827         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22828                 error "MDT stripe wasn't set"
22829
22830         cancel_lru_locks
22831         local new_md5=$(md5sum $dom)
22832         [ "$old_md5" == "$new_md5" ] ||
22833                 error "$old_md5 != $new_md5"
22834
22835         return 0
22836 }
22837 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22838
22839 test_272f() {
22840         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22841                 skip "Need MDS version at least 2.12.55"
22842
22843         local dom=$DIR/$tdir/$tfile
22844         mkdir -p $DIR/$tdir
22845         $LFS setstripe -c 2 $dom
22846
22847         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22848                 error "failed to write data into $dom"
22849         local old_md5=$(md5sum $dom)
22850         cancel_lru_locks
22851
22852         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22853                 error "failed migrating to the DOM file"
22854
22855         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22856                 error "MDT stripe wasn't set"
22857
22858         cancel_lru_locks
22859         local new_md5=$(md5sum $dom)
22860         [ "$old_md5" != "$new_md5" ] &&
22861                 error "$old_md5 != $new_md5"
22862
22863         return 0
22864 }
22865 run_test 272f "DoM migration: OST-striped file to DOM file"
22866
22867 test_273a() {
22868         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22869                 skip "Need MDS version at least 2.11.50"
22870
22871         # Layout swap cannot be done if either file has DOM component,
22872         # this will never be supported, migration should be used instead
22873
22874         local dom=$DIR/$tdir/$tfile
22875         mkdir -p $DIR/$tdir
22876
22877         $LFS setstripe -c2 ${dom}_plain
22878         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22879         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22880                 error "can swap layout with DoM component"
22881         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22882                 error "can swap layout with DoM component"
22883
22884         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22885         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22886                 error "can swap layout with DoM component"
22887         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22888                 error "can swap layout with DoM component"
22889         return 0
22890 }
22891 run_test 273a "DoM: layout swapping should fail with DOM"
22892
22893 test_273b() {
22894         mkdir -p $DIR/$tdir
22895         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22896
22897 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22898         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22899
22900         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22901 }
22902 run_test 273b "DoM: race writeback and object destroy"
22903
22904 test_275() {
22905         remote_ost_nodsh && skip "remote OST with nodsh"
22906         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22907                 skip "Need OST version >= 2.10.57"
22908
22909         local file=$DIR/$tfile
22910         local oss
22911
22912         oss=$(comma_list $(osts_nodes))
22913
22914         dd if=/dev/urandom of=$file bs=1M count=2 ||
22915                 error "failed to create a file"
22916         cancel_lru_locks osc
22917
22918         #lock 1
22919         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22920                 error "failed to read a file"
22921
22922 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22923         $LCTL set_param fail_loc=0x8000031f
22924
22925         cancel_lru_locks osc &
22926         sleep 1
22927
22928 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22929         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22930         #IO takes another lock, but matches the PENDING one
22931         #and places it to the IO RPC
22932         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22933                 error "failed to read a file with PENDING lock"
22934 }
22935 run_test 275 "Read on a canceled duplicate lock"
22936
22937 test_276() {
22938         remote_ost_nodsh && skip "remote OST with nodsh"
22939         local pid
22940
22941         do_facet ost1 "(while true; do \
22942                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22943                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22944         pid=$!
22945
22946         for LOOP in $(seq 20); do
22947                 stop ost1
22948                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22949         done
22950         kill -9 $pid
22951         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22952                 rm $TMP/sanity_276_pid"
22953 }
22954 run_test 276 "Race between mount and obd_statfs"
22955
22956 test_277() {
22957         $LCTL set_param ldlm.namespaces.*.lru_size=0
22958         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22959         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22960                         grep ^used_mb | awk '{print $2}')
22961         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22962         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22963                 oflag=direct conv=notrunc
22964         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22965                         grep ^used_mb | awk '{print $2}')
22966         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22967 }
22968 run_test 277 "Direct IO shall drop page cache"
22969
22970 test_278() {
22971         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22972         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22973         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22974                 skip "needs the same host for mdt1 mdt2" && return
22975
22976         local pid1
22977         local pid2
22978
22979 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22980         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22981         stop mds2 &
22982         pid2=$!
22983
22984         stop mds1
22985
22986         echo "Starting MDTs"
22987         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22988         wait $pid2
22989 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22990 #will return NULL
22991         do_facet mds2 $LCTL set_param fail_loc=0
22992
22993         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22994         wait_recovery_complete mds2
22995 }
22996 run_test 278 "Race starting MDS between MDTs stop/start"
22997
22998 test_280() {
22999         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23000                 skip "Need MGS version at least 2.13.52"
23001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23002         combined_mgs_mds || skip "needs combined MGS/MDT"
23003
23004         umount_client $MOUNT
23005 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23006         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23007
23008         mount_client $MOUNT &
23009         sleep 1
23010         stop mgs || error "stop mgs failed"
23011         #for a race mgs would crash
23012         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23013         # make sure we unmount client before remounting
23014         wait
23015         umount_client $MOUNT
23016         mount_client $MOUNT || error "mount client failed"
23017 }
23018 run_test 280 "Race between MGS umount and client llog processing"
23019
23020 cleanup_test_300() {
23021         trap 0
23022         umask $SAVE_UMASK
23023 }
23024 test_striped_dir() {
23025         local mdt_index=$1
23026         local stripe_count
23027         local stripe_index
23028
23029         mkdir -p $DIR/$tdir
23030
23031         SAVE_UMASK=$(umask)
23032         trap cleanup_test_300 RETURN EXIT
23033
23034         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23035                                                 $DIR/$tdir/striped_dir ||
23036                 error "set striped dir error"
23037
23038         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23039         [ "$mode" = "755" ] || error "expect 755 got $mode"
23040
23041         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23042                 error "getdirstripe failed"
23043         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23044         if [ "$stripe_count" != "2" ]; then
23045                 error "1:stripe_count is $stripe_count, expect 2"
23046         fi
23047         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23048         if [ "$stripe_count" != "2" ]; then
23049                 error "2:stripe_count is $stripe_count, expect 2"
23050         fi
23051
23052         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23053         if [ "$stripe_index" != "$mdt_index" ]; then
23054                 error "stripe_index is $stripe_index, expect $mdt_index"
23055         fi
23056
23057         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23058                 error "nlink error after create striped dir"
23059
23060         mkdir $DIR/$tdir/striped_dir/a
23061         mkdir $DIR/$tdir/striped_dir/b
23062
23063         stat $DIR/$tdir/striped_dir/a ||
23064                 error "create dir under striped dir failed"
23065         stat $DIR/$tdir/striped_dir/b ||
23066                 error "create dir under striped dir failed"
23067
23068         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23069                 error "nlink error after mkdir"
23070
23071         rmdir $DIR/$tdir/striped_dir/a
23072         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23073                 error "nlink error after rmdir"
23074
23075         rmdir $DIR/$tdir/striped_dir/b
23076         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23077                 error "nlink error after rmdir"
23078
23079         chattr +i $DIR/$tdir/striped_dir
23080         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23081                 error "immutable flags not working under striped dir!"
23082         chattr -i $DIR/$tdir/striped_dir
23083
23084         rmdir $DIR/$tdir/striped_dir ||
23085                 error "rmdir striped dir error"
23086
23087         cleanup_test_300
23088
23089         true
23090 }
23091
23092 test_300a() {
23093         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23094                 skip "skipped for lustre < 2.7.0"
23095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23096         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23097
23098         test_striped_dir 0 || error "failed on striped dir on MDT0"
23099         test_striped_dir 1 || error "failed on striped dir on MDT0"
23100 }
23101 run_test 300a "basic striped dir sanity test"
23102
23103 test_300b() {
23104         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23105                 skip "skipped for lustre < 2.7.0"
23106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23107         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23108
23109         local i
23110         local mtime1
23111         local mtime2
23112         local mtime3
23113
23114         test_mkdir $DIR/$tdir || error "mkdir fail"
23115         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23116                 error "set striped dir error"
23117         for i in {0..9}; do
23118                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23119                 sleep 1
23120                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23121                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23122                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23123                 sleep 1
23124                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23125                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23126                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23127         done
23128         true
23129 }
23130 run_test 300b "check ctime/mtime for striped dir"
23131
23132 test_300c() {
23133         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23134                 skip "skipped for lustre < 2.7.0"
23135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23136         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23137
23138         local file_count
23139
23140         mkdir_on_mdt0 $DIR/$tdir
23141         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23142                 error "set striped dir error"
23143
23144         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23145                 error "chown striped dir failed"
23146
23147         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23148                 error "create 5k files failed"
23149
23150         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23151
23152         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23153
23154         rm -rf $DIR/$tdir
23155 }
23156 run_test 300c "chown && check ls under striped directory"
23157
23158 test_300d() {
23159         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23160                 skip "skipped for lustre < 2.7.0"
23161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23162         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23163
23164         local stripe_count
23165         local file
23166
23167         mkdir -p $DIR/$tdir
23168         $LFS setstripe -c 2 $DIR/$tdir
23169
23170         #local striped directory
23171         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23172                 error "set striped dir error"
23173         #look at the directories for debug purposes
23174         ls -l $DIR/$tdir
23175         $LFS getdirstripe $DIR/$tdir
23176         ls -l $DIR/$tdir/striped_dir
23177         $LFS getdirstripe $DIR/$tdir/striped_dir
23178         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23179                 error "create 10 files failed"
23180
23181         #remote striped directory
23182         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23183                 error "set striped dir error"
23184         #look at the directories for debug purposes
23185         ls -l $DIR/$tdir
23186         $LFS getdirstripe $DIR/$tdir
23187         ls -l $DIR/$tdir/remote_striped_dir
23188         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23189         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23190                 error "create 10 files failed"
23191
23192         for file in $(find $DIR/$tdir); do
23193                 stripe_count=$($LFS getstripe -c $file)
23194                 [ $stripe_count -eq 2 ] ||
23195                         error "wrong stripe $stripe_count for $file"
23196         done
23197
23198         rm -rf $DIR/$tdir
23199 }
23200 run_test 300d "check default stripe under striped directory"
23201
23202 test_300e() {
23203         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23204                 skip "Need MDS version at least 2.7.55"
23205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23206         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23207
23208         local stripe_count
23209         local file
23210
23211         mkdir -p $DIR/$tdir
23212
23213         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23214                 error "set striped dir error"
23215
23216         touch $DIR/$tdir/striped_dir/a
23217         touch $DIR/$tdir/striped_dir/b
23218         touch $DIR/$tdir/striped_dir/c
23219
23220         mkdir $DIR/$tdir/striped_dir/dir_a
23221         mkdir $DIR/$tdir/striped_dir/dir_b
23222         mkdir $DIR/$tdir/striped_dir/dir_c
23223
23224         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23225                 error "set striped adir under striped dir error"
23226
23227         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23228                 error "set striped bdir under striped dir error"
23229
23230         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23231                 error "set striped cdir under striped dir error"
23232
23233         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23234                 error "rename dir under striped dir fails"
23235
23236         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23237                 error "rename dir under different stripes fails"
23238
23239         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23240                 error "rename file under striped dir should succeed"
23241
23242         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23243                 error "rename dir under striped dir should succeed"
23244
23245         rm -rf $DIR/$tdir
23246 }
23247 run_test 300e "check rename under striped directory"
23248
23249 test_300f() {
23250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23251         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23252         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23253                 skip "Need MDS version at least 2.7.55"
23254
23255         local stripe_count
23256         local file
23257
23258         rm -rf $DIR/$tdir
23259         mkdir -p $DIR/$tdir
23260
23261         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23262                 error "set striped dir error"
23263
23264         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23265                 error "set striped dir error"
23266
23267         touch $DIR/$tdir/striped_dir/a
23268         mkdir $DIR/$tdir/striped_dir/dir_a
23269         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23270                 error "create striped dir under striped dir fails"
23271
23272         touch $DIR/$tdir/striped_dir1/b
23273         mkdir $DIR/$tdir/striped_dir1/dir_b
23274         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23275                 error "create striped dir under striped dir fails"
23276
23277         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23278                 error "rename dir under different striped dir should fail"
23279
23280         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23281                 error "rename striped dir under diff striped dir should fail"
23282
23283         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23284                 error "rename file under diff striped dirs fails"
23285
23286         rm -rf $DIR/$tdir
23287 }
23288 run_test 300f "check rename cross striped directory"
23289
23290 test_300_check_default_striped_dir()
23291 {
23292         local dirname=$1
23293         local default_count=$2
23294         local default_index=$3
23295         local stripe_count
23296         local stripe_index
23297         local dir_stripe_index
23298         local dir
23299
23300         echo "checking $dirname $default_count $default_index"
23301         $LFS setdirstripe -D -c $default_count -i $default_index \
23302                                 -H all_char $DIR/$tdir/$dirname ||
23303                 error "set default stripe on striped dir error"
23304         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23305         [ $stripe_count -eq $default_count ] ||
23306                 error "expect $default_count get $stripe_count for $dirname"
23307
23308         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23309         [ $stripe_index -eq $default_index ] ||
23310                 error "expect $default_index get $stripe_index for $dirname"
23311
23312         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23313                                                 error "create dirs failed"
23314
23315         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23316         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23317         for dir in $(find $DIR/$tdir/$dirname/*); do
23318                 stripe_count=$($LFS getdirstripe -c $dir)
23319                 (( $stripe_count == $default_count )) ||
23320                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23321                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23322                 error "stripe count $default_count != $stripe_count for $dir"
23323
23324                 stripe_index=$($LFS getdirstripe -i $dir)
23325                 [ $default_index -eq -1 ] ||
23326                         [ $stripe_index -eq $default_index ] ||
23327                         error "$stripe_index != $default_index for $dir"
23328
23329                 #check default stripe
23330                 stripe_count=$($LFS getdirstripe -D -c $dir)
23331                 [ $stripe_count -eq $default_count ] ||
23332                 error "default count $default_count != $stripe_count for $dir"
23333
23334                 stripe_index=$($LFS getdirstripe -D -i $dir)
23335                 [ $stripe_index -eq $default_index ] ||
23336                 error "default index $default_index != $stripe_index for $dir"
23337         done
23338         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23339 }
23340
23341 test_300g() {
23342         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23343         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23344                 skip "Need MDS version at least 2.7.55"
23345
23346         local dir
23347         local stripe_count
23348         local stripe_index
23349
23350         mkdir_on_mdt0 $DIR/$tdir
23351         mkdir $DIR/$tdir/normal_dir
23352
23353         #Checking when client cache stripe index
23354         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23355         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23356                 error "create striped_dir failed"
23357
23358         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23359                 error "create dir0 fails"
23360         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23361         [ $stripe_index -eq 0 ] ||
23362                 error "dir0 expect index 0 got $stripe_index"
23363
23364         mkdir $DIR/$tdir/striped_dir/dir1 ||
23365                 error "create dir1 fails"
23366         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23367         [ $stripe_index -eq 1 ] ||
23368                 error "dir1 expect index 1 got $stripe_index"
23369
23370         #check default stripe count/stripe index
23371         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23372         test_300_check_default_striped_dir normal_dir 1 0
23373         test_300_check_default_striped_dir normal_dir -1 1
23374         test_300_check_default_striped_dir normal_dir 2 -1
23375
23376         #delete default stripe information
23377         echo "delete default stripeEA"
23378         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23379                 error "set default stripe on striped dir error"
23380
23381         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23382         for dir in $(find $DIR/$tdir/normal_dir/*); do
23383                 stripe_count=$($LFS getdirstripe -c $dir)
23384                 [ $stripe_count -eq 0 ] ||
23385                         error "expect 1 get $stripe_count for $dir"
23386         done
23387 }
23388 run_test 300g "check default striped directory for normal directory"
23389
23390 test_300h() {
23391         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23392         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23393                 skip "Need MDS version at least 2.7.55"
23394
23395         local dir
23396         local stripe_count
23397
23398         mkdir $DIR/$tdir
23399         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23400                 error "set striped dir error"
23401
23402         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23403         test_300_check_default_striped_dir striped_dir 1 0
23404         test_300_check_default_striped_dir striped_dir -1 1
23405         test_300_check_default_striped_dir striped_dir 2 -1
23406
23407         #delete default stripe information
23408         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23409                 error "set default stripe on striped dir error"
23410
23411         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23412         for dir in $(find $DIR/$tdir/striped_dir/*); do
23413                 stripe_count=$($LFS getdirstripe -c $dir)
23414                 [ $stripe_count -eq 0 ] ||
23415                         error "expect 1 get $stripe_count for $dir"
23416         done
23417 }
23418 run_test 300h "check default striped directory for striped directory"
23419
23420 test_300i() {
23421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23422         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23423         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23424                 skip "Need MDS version at least 2.7.55"
23425
23426         local stripe_count
23427         local file
23428
23429         mkdir $DIR/$tdir
23430
23431         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23432                 error "set striped dir error"
23433
23434         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23435                 error "create files under striped dir failed"
23436
23437         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23438                 error "set striped hashdir error"
23439
23440         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23441                 error "create dir0 under hash dir failed"
23442         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23443                 error "create dir1 under hash dir failed"
23444         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23445                 error "create dir2 under hash dir failed"
23446
23447         # unfortunately, we need to umount to clear dir layout cache for now
23448         # once we fully implement dir layout, we can drop this
23449         umount_client $MOUNT || error "umount failed"
23450         mount_client $MOUNT || error "mount failed"
23451
23452         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23453         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23454         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23455
23456         #set the stripe to be unknown hash type
23457         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23458         $LCTL set_param fail_loc=0x1901
23459         for ((i = 0; i < 10; i++)); do
23460                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23461                         error "stat f-$i failed"
23462                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23463         done
23464
23465         touch $DIR/$tdir/striped_dir/f0 &&
23466                 error "create under striped dir with unknown hash should fail"
23467
23468         $LCTL set_param fail_loc=0
23469
23470         umount_client $MOUNT || error "umount failed"
23471         mount_client $MOUNT || error "mount failed"
23472
23473         return 0
23474 }
23475 run_test 300i "client handle unknown hash type striped directory"
23476
23477 test_300j() {
23478         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23480         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23481                 skip "Need MDS version at least 2.7.55"
23482
23483         local stripe_count
23484         local file
23485
23486         mkdir $DIR/$tdir
23487
23488         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23489         $LCTL set_param fail_loc=0x1702
23490         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23491                 error "set striped dir error"
23492
23493         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23494                 error "create files under striped dir failed"
23495
23496         $LCTL set_param fail_loc=0
23497
23498         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23499
23500         return 0
23501 }
23502 run_test 300j "test large update record"
23503
23504 test_300k() {
23505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23506         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23507         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23508                 skip "Need MDS version at least 2.7.55"
23509
23510         # this test needs a huge transaction
23511         local kb
23512         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23513              osd*.$FSNAME-MDT0000.kbytestotal")
23514         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23515
23516         local stripe_count
23517         local file
23518
23519         mkdir $DIR/$tdir
23520
23521         #define OBD_FAIL_LARGE_STRIPE   0x1703
23522         $LCTL set_param fail_loc=0x1703
23523         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23524                 error "set striped dir error"
23525         $LCTL set_param fail_loc=0
23526
23527         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23528                 error "getstripeddir fails"
23529         rm -rf $DIR/$tdir/striped_dir ||
23530                 error "unlink striped dir fails"
23531
23532         return 0
23533 }
23534 run_test 300k "test large striped directory"
23535
23536 test_300l() {
23537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23538         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23539         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23540                 skip "Need MDS version at least 2.7.55"
23541
23542         local stripe_index
23543
23544         test_mkdir -p $DIR/$tdir/striped_dir
23545         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23546                         error "chown $RUNAS_ID failed"
23547         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23548                 error "set default striped dir failed"
23549
23550         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23551         $LCTL set_param fail_loc=0x80000158
23552         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23553
23554         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23555         [ $stripe_index -eq 1 ] ||
23556                 error "expect 1 get $stripe_index for $dir"
23557 }
23558 run_test 300l "non-root user to create dir under striped dir with stale layout"
23559
23560 test_300m() {
23561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23562         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23563         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23564                 skip "Need MDS version at least 2.7.55"
23565
23566         mkdir -p $DIR/$tdir/striped_dir
23567         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23568                 error "set default stripes dir error"
23569
23570         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23571
23572         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23573         [ $stripe_count -eq 0 ] ||
23574                         error "expect 0 get $stripe_count for a"
23575
23576         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23577                 error "set default stripes dir error"
23578
23579         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23580
23581         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23582         [ $stripe_count -eq 0 ] ||
23583                         error "expect 0 get $stripe_count for b"
23584
23585         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23586                 error "set default stripes dir error"
23587
23588         mkdir $DIR/$tdir/striped_dir/c &&
23589                 error "default stripe_index is invalid, mkdir c should fails"
23590
23591         rm -rf $DIR/$tdir || error "rmdir fails"
23592 }
23593 run_test 300m "setstriped directory on single MDT FS"
23594
23595 cleanup_300n() {
23596         local list=$(comma_list $(mdts_nodes))
23597
23598         trap 0
23599         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23600 }
23601
23602 test_300n() {
23603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23604         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23605         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23606                 skip "Need MDS version at least 2.7.55"
23607         remote_mds_nodsh && skip "remote MDS with nodsh"
23608
23609         local stripe_index
23610         local list=$(comma_list $(mdts_nodes))
23611
23612         trap cleanup_300n RETURN EXIT
23613         mkdir -p $DIR/$tdir
23614         chmod 777 $DIR/$tdir
23615         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23616                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23617                 error "create striped dir succeeds with gid=0"
23618
23619         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23620         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23621                 error "create striped dir fails with gid=-1"
23622
23623         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23624         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23625                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23626                 error "set default striped dir succeeds with gid=0"
23627
23628
23629         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23630         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23631                 error "set default striped dir fails with gid=-1"
23632
23633
23634         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23635         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23636                                         error "create test_dir fails"
23637         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23638                                         error "create test_dir1 fails"
23639         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23640                                         error "create test_dir2 fails"
23641         cleanup_300n
23642 }
23643 run_test 300n "non-root user to create dir under striped dir with default EA"
23644
23645 test_300o() {
23646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23647         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23648         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23649                 skip "Need MDS version at least 2.7.55"
23650
23651         local numfree1
23652         local numfree2
23653
23654         mkdir -p $DIR/$tdir
23655
23656         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23657         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23658         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23659                 skip "not enough free inodes $numfree1 $numfree2"
23660         fi
23661
23662         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23663         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23664         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23665                 skip "not enough free space $numfree1 $numfree2"
23666         fi
23667
23668         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23669                 error "setdirstripe fails"
23670
23671         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23672                 error "create dirs fails"
23673
23674         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23675         ls $DIR/$tdir/striped_dir > /dev/null ||
23676                 error "ls striped dir fails"
23677         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23678                 error "unlink big striped dir fails"
23679 }
23680 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23681
23682 test_300p() {
23683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23684         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23685         remote_mds_nodsh && skip "remote MDS with nodsh"
23686
23687         mkdir_on_mdt0 $DIR/$tdir
23688
23689         #define OBD_FAIL_OUT_ENOSPC     0x1704
23690         do_facet mds2 lctl set_param fail_loc=0x80001704
23691         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23692                  && error "create striped directory should fail"
23693
23694         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23695
23696         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23697         true
23698 }
23699 run_test 300p "create striped directory without space"
23700
23701 test_300q() {
23702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23703         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23704
23705         local fd=$(free_fd)
23706         local cmd="exec $fd<$tdir"
23707         cd $DIR
23708         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23709         eval $cmd
23710         cmd="exec $fd<&-"
23711         trap "eval $cmd" EXIT
23712         cd $tdir || error "cd $tdir fails"
23713         rmdir  ../$tdir || error "rmdir $tdir fails"
23714         mkdir local_dir && error "create dir succeeds"
23715         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23716         eval $cmd
23717         return 0
23718 }
23719 run_test 300q "create remote directory under orphan directory"
23720
23721 test_300r() {
23722         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23723                 skip "Need MDS version at least 2.7.55" && return
23724         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23725
23726         mkdir $DIR/$tdir
23727
23728         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23729                 error "set striped dir error"
23730
23731         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23732                 error "getstripeddir fails"
23733
23734         local stripe_count
23735         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23736                       awk '/lmv_stripe_count:/ { print $2 }')
23737
23738         [ $MDSCOUNT -ne $stripe_count ] &&
23739                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23740
23741         rm -rf $DIR/$tdir/striped_dir ||
23742                 error "unlink striped dir fails"
23743 }
23744 run_test 300r "test -1 striped directory"
23745
23746 test_300s_helper() {
23747         local count=$1
23748
23749         local stripe_dir=$DIR/$tdir/striped_dir.$count
23750
23751         $LFS mkdir -c $count $stripe_dir ||
23752                 error "lfs mkdir -c error"
23753
23754         $LFS getdirstripe $stripe_dir ||
23755                 error "lfs getdirstripe fails"
23756
23757         local stripe_count
23758         stripe_count=$($LFS getdirstripe $stripe_dir |
23759                       awk '/lmv_stripe_count:/ { print $2 }')
23760
23761         [ $count -ne $stripe_count ] &&
23762                 error_noexit "bad stripe count $stripe_count expected $count"
23763
23764         local dupe_stripes
23765         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23766                 awk '/0x/ {count[$1] += 1}; END {
23767                         for (idx in count) {
23768                                 if (count[idx]>1) {
23769                                         print "index " idx " count " count[idx]
23770                                 }
23771                         }
23772                 }')
23773
23774         if [[ -n "$dupe_stripes" ]] ; then
23775                 lfs getdirstripe $stripe_dir
23776                 error_noexit "Dupe MDT above: $dupe_stripes "
23777         fi
23778
23779         rm -rf $stripe_dir ||
23780                 error_noexit "unlink $stripe_dir fails"
23781 }
23782
23783 test_300s() {
23784         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23785                 skip "Need MDS version at least 2.7.55" && return
23786         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23787
23788         mkdir $DIR/$tdir
23789         for count in $(seq 2 $MDSCOUNT); do
23790                 test_300s_helper $count
23791         done
23792 }
23793 run_test 300s "test lfs mkdir -c without -i"
23794
23795 test_300t() {
23796         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23797                 skip "need MDS 2.14.55 or later"
23798         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23799
23800         local testdir="$DIR/$tdir/striped_dir"
23801         local dir1=$testdir/dir1
23802         local dir2=$testdir/dir2
23803
23804         mkdir -p $testdir
23805
23806         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23807                 error "failed to set default stripe count for $testdir"
23808
23809         mkdir $dir1
23810         local stripe_count=$($LFS getdirstripe -c $dir1)
23811
23812         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23813
23814         local max_count=$((MDSCOUNT - 1))
23815         local mdts=$(comma_list $(mdts_nodes))
23816
23817         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23818         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23819
23820         mkdir $dir2
23821         stripe_count=$($LFS getdirstripe -c $dir2)
23822
23823         (( $stripe_count == $max_count )) || error "wrong stripe count"
23824 }
23825 run_test 300t "test max_mdt_stripecount"
23826
23827 prepare_remote_file() {
23828         mkdir $DIR/$tdir/src_dir ||
23829                 error "create remote source failed"
23830
23831         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23832                  error "cp to remote source failed"
23833         touch $DIR/$tdir/src_dir/a
23834
23835         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23836                 error "create remote target dir failed"
23837
23838         touch $DIR/$tdir/tgt_dir/b
23839
23840         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23841                 error "rename dir cross MDT failed!"
23842
23843         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23844                 error "src_child still exists after rename"
23845
23846         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23847                 error "missing file(a) after rename"
23848
23849         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23850                 error "diff after rename"
23851 }
23852
23853 test_310a() {
23854         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23856
23857         local remote_file=$DIR/$tdir/tgt_dir/b
23858
23859         mkdir -p $DIR/$tdir
23860
23861         prepare_remote_file || error "prepare remote file failed"
23862
23863         #open-unlink file
23864         $OPENUNLINK $remote_file $remote_file ||
23865                 error "openunlink $remote_file failed"
23866         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23867 }
23868 run_test 310a "open unlink remote file"
23869
23870 test_310b() {
23871         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23873
23874         local remote_file=$DIR/$tdir/tgt_dir/b
23875
23876         mkdir -p $DIR/$tdir
23877
23878         prepare_remote_file || error "prepare remote file failed"
23879
23880         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23881         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23882         $CHECKSTAT -t file $remote_file || error "check file failed"
23883 }
23884 run_test 310b "unlink remote file with multiple links while open"
23885
23886 test_310c() {
23887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23888         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23889
23890         local remote_file=$DIR/$tdir/tgt_dir/b
23891
23892         mkdir -p $DIR/$tdir
23893
23894         prepare_remote_file || error "prepare remote file failed"
23895
23896         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23897         multiop_bg_pause $remote_file O_uc ||
23898                         error "mulitop failed for remote file"
23899         MULTIPID=$!
23900         $MULTIOP $DIR/$tfile Ouc
23901         kill -USR1 $MULTIPID
23902         wait $MULTIPID
23903 }
23904 run_test 310c "open-unlink remote file with multiple links"
23905
23906 #LU-4825
23907 test_311() {
23908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23909         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23910         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23911                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23912         remote_mds_nodsh && skip "remote MDS with nodsh"
23913
23914         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23915         local mdts=$(comma_list $(mdts_nodes))
23916
23917         mkdir -p $DIR/$tdir
23918         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23919         createmany -o $DIR/$tdir/$tfile. 1000
23920
23921         # statfs data is not real time, let's just calculate it
23922         old_iused=$((old_iused + 1000))
23923
23924         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23925                         osp.*OST0000*MDT0000.create_count")
23926         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23927                                 osp.*OST0000*MDT0000.max_create_count")
23928         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23929
23930         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23931         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23932         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23933
23934         unlinkmany $DIR/$tdir/$tfile. 1000
23935
23936         do_nodes $mdts "$LCTL set_param -n \
23937                         osp.*OST0000*.max_create_count=$max_count"
23938         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23939                 do_nodes $mdts "$LCTL set_param -n \
23940                                 osp.*OST0000*.create_count=$count"
23941         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23942                         grep "=0" && error "create_count is zero"
23943
23944         local new_iused
23945         for i in $(seq 120); do
23946                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23947                 # system may be too busy to destroy all objs in time, use
23948                 # a somewhat small value to not fail autotest
23949                 [ $((old_iused - new_iused)) -gt 400 ] && break
23950                 sleep 1
23951         done
23952
23953         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23954         [ $((old_iused - new_iused)) -gt 400 ] ||
23955                 error "objs not destroyed after unlink"
23956 }
23957 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23958
23959 zfs_oid_to_objid()
23960 {
23961         local ost=$1
23962         local objid=$2
23963
23964         local vdevdir=$(dirname $(facet_vdevice $ost))
23965         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23966         local zfs_zapid=$(do_facet $ost $cmd |
23967                           grep -w "/O/0/d$((objid%32))" -C 5 |
23968                           awk '/Object/{getline; print $1}')
23969         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23970                           awk "/$objid = /"'{printf $3}')
23971
23972         echo $zfs_objid
23973 }
23974
23975 zfs_object_blksz() {
23976         local ost=$1
23977         local objid=$2
23978
23979         local vdevdir=$(dirname $(facet_vdevice $ost))
23980         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23981         local blksz=$(do_facet $ost $cmd $objid |
23982                       awk '/dblk/{getline; printf $4}')
23983
23984         case "${blksz: -1}" in
23985                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23986                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23987                 *) ;;
23988         esac
23989
23990         echo $blksz
23991 }
23992
23993 test_312() { # LU-4856
23994         remote_ost_nodsh && skip "remote OST with nodsh"
23995         [ "$ost1_FSTYPE" = "zfs" ] ||
23996                 skip_env "the test only applies to zfs"
23997
23998         local max_blksz=$(do_facet ost1 \
23999                           $ZFS get -p recordsize $(facet_device ost1) |
24000                           awk '!/VALUE/{print $3}')
24001
24002         # to make life a little bit easier
24003         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24004         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24005
24006         local tf=$DIR/$tdir/$tfile
24007         touch $tf
24008         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24009
24010         # Get ZFS object id
24011         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24012         # block size change by sequential overwrite
24013         local bs
24014
24015         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24016                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24017
24018                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24019                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24020         done
24021         rm -f $tf
24022
24023         # block size change by sequential append write
24024         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24025         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24026         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24027         local count
24028
24029         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24030                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24031                         oflag=sync conv=notrunc
24032
24033                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24034                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24035                         error "blksz error, actual $blksz, " \
24036                                 "expected: 2 * $count * $PAGE_SIZE"
24037         done
24038         rm -f $tf
24039
24040         # random write
24041         touch $tf
24042         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24043         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24044
24045         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24046         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24047         [ $blksz -eq $PAGE_SIZE ] ||
24048                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24049
24050         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24051         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24052         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24053
24054         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24055         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24056         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24057 }
24058 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24059
24060 test_313() {
24061         remote_ost_nodsh && skip "remote OST with nodsh"
24062
24063         local file=$DIR/$tfile
24064
24065         rm -f $file
24066         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24067
24068         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24069         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24070         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24071                 error "write should failed"
24072         do_facet ost1 "$LCTL set_param fail_loc=0"
24073         rm -f $file
24074 }
24075 run_test 313 "io should fail after last_rcvd update fail"
24076
24077 test_314() {
24078         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24079
24080         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24081         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24082         rm -f $DIR/$tfile
24083         wait_delete_completed
24084         do_facet ost1 "$LCTL set_param fail_loc=0"
24085 }
24086 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24087
24088 test_315() { # LU-618
24089         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24090
24091         local file=$DIR/$tfile
24092         rm -f $file
24093
24094         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24095                 error "multiop file write failed"
24096         $MULTIOP $file oO_RDONLY:r4063232_c &
24097         PID=$!
24098
24099         sleep 2
24100
24101         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24102         kill -USR1 $PID
24103
24104         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24105         rm -f $file
24106 }
24107 run_test 315 "read should be accounted"
24108
24109 test_316() {
24110         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24111         large_xattr_enabled || skip "ea_inode feature disabled"
24112
24113         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24114         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24115         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24116         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24117
24118         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24119 }
24120 run_test 316 "lfs migrate of file with large_xattr enabled"
24121
24122 test_317() {
24123         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24124                 skip "Need MDS version at least 2.11.53"
24125         if [ "$ost1_FSTYPE" == "zfs" ]; then
24126                 skip "LU-10370: no implementation for ZFS"
24127         fi
24128
24129         local trunc_sz
24130         local grant_blk_size
24131
24132         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24133                         awk '/grant_block_size:/ { print $2; exit; }')
24134         #
24135         # Create File of size 5M. Truncate it to below size's and verify
24136         # blocks count.
24137         #
24138         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24139                 error "Create file $DIR/$tfile failed"
24140         stack_trap "rm -f $DIR/$tfile" EXIT
24141
24142         for trunc_sz in 2097152 4097 4000 509 0; do
24143                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24144                         error "truncate $tfile to $trunc_sz failed"
24145                 local sz=$(stat --format=%s $DIR/$tfile)
24146                 local blk=$(stat --format=%b $DIR/$tfile)
24147                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24148                                      grant_blk_size) * 8))
24149
24150                 if [[ $blk -ne $trunc_blk ]]; then
24151                         $(which stat) $DIR/$tfile
24152                         error "Expected Block $trunc_blk got $blk for $tfile"
24153                 fi
24154
24155                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24156                         error "Expected Size $trunc_sz got $sz for $tfile"
24157         done
24158
24159         #
24160         # sparse file test
24161         # Create file with a hole and write actual 65536 bytes which aligned
24162         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24163         #
24164         local bs=65536
24165         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24166                 error "Create file : $DIR/$tfile"
24167
24168         #
24169         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24170         # blocks. The block count must drop to 8.
24171         #
24172         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24173                 ((bs - grant_blk_size) + 1)))
24174         $TRUNCATE $DIR/$tfile $trunc_sz ||
24175                 error "truncate $tfile to $trunc_sz failed"
24176
24177         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24178         sz=$(stat --format=%s $DIR/$tfile)
24179         blk=$(stat --format=%b $DIR/$tfile)
24180
24181         if [[ $blk -ne $trunc_bsz ]]; then
24182                 $(which stat) $DIR/$tfile
24183                 error "Expected Block $trunc_bsz got $blk for $tfile"
24184         fi
24185
24186         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24187                 error "Expected Size $trunc_sz got $sz for $tfile"
24188 }
24189 run_test 317 "Verify blocks get correctly update after truncate"
24190
24191 test_318() {
24192         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24193         local old_max_active=$($LCTL get_param -n \
24194                             ${llite_name}.max_read_ahead_async_active \
24195                             2>/dev/null)
24196
24197         $LCTL set_param llite.*.max_read_ahead_async_active=256
24198         local max_active=$($LCTL get_param -n \
24199                            ${llite_name}.max_read_ahead_async_active \
24200                            2>/dev/null)
24201         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24202
24203         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24204                 error "set max_read_ahead_async_active should succeed"
24205
24206         $LCTL set_param llite.*.max_read_ahead_async_active=512
24207         max_active=$($LCTL get_param -n \
24208                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24209         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24210
24211         # restore @max_active
24212         [ $old_max_active -ne 0 ] && $LCTL set_param \
24213                 llite.*.max_read_ahead_async_active=$old_max_active
24214
24215         local old_threshold=$($LCTL get_param -n \
24216                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24217         local max_per_file_mb=$($LCTL get_param -n \
24218                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24219
24220         local invalid=$(($max_per_file_mb + 1))
24221         $LCTL set_param \
24222                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24223                         && error "set $invalid should fail"
24224
24225         local valid=$(($invalid - 1))
24226         $LCTL set_param \
24227                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24228                         error "set $valid should succeed"
24229         local threshold=$($LCTL get_param -n \
24230                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24231         [ $threshold -eq $valid ] || error \
24232                 "expect threshold $valid got $threshold"
24233         $LCTL set_param \
24234                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24235 }
24236 run_test 318 "Verify async readahead tunables"
24237
24238 test_319() {
24239         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24240
24241         local before=$(date +%s)
24242         local evict
24243         local mdir=$DIR/$tdir
24244         local file=$mdir/xxx
24245
24246         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24247         touch $file
24248
24249 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24250         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24251         $LFS migrate -m1 $mdir &
24252
24253         sleep 1
24254         dd if=$file of=/dev/null
24255         wait
24256         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24257           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24258
24259         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24260 }
24261 run_test 319 "lost lease lock on migrate error"
24262
24263 test_398a() { # LU-4198
24264         local ost1_imp=$(get_osc_import_name client ost1)
24265         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24266                          cut -d'.' -f2)
24267
24268         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24269         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24270
24271         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24272         # request a new lock on client
24273         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24274
24275         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24276         #local lock_count=$($LCTL get_param -n \
24277         #                  ldlm.namespaces.$imp_name.lru_size)
24278         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24279
24280         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24281
24282         # no lock cached, should use lockless DIO and not enqueue new lock
24283         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24284                 conv=notrunc ||
24285                 error "dio write failed"
24286         lock_count=$($LCTL get_param -n \
24287                      ldlm.namespaces.$imp_name.lru_size)
24288         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24289
24290         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24291
24292         # no lock cached, should use locked DIO append
24293         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24294                 conv=notrunc || error "DIO append failed"
24295         lock_count=$($LCTL get_param -n \
24296                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24297         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24298 }
24299 run_test 398a "direct IO should cancel lock otherwise lockless"
24300
24301 test_398b() { # LU-4198
24302         which fio || skip_env "no fio installed"
24303         $LFS setstripe -c -1 $DIR/$tfile
24304
24305         local size=12
24306         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24307
24308         local njobs=4
24309         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24310         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24311                 --numjobs=$njobs --fallocate=none \
24312                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24313                 --filename=$DIR/$tfile &
24314         bg_pid=$!
24315
24316         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24317         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24318                 --numjobs=$njobs --fallocate=none \
24319                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24320                 --filename=$DIR/$tfile || true
24321         wait $bg_pid
24322
24323         rm -f $DIR/$tfile
24324 }
24325 run_test 398b "DIO and buffer IO race"
24326
24327 test_398c() { # LU-4198
24328         local ost1_imp=$(get_osc_import_name client ost1)
24329         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24330                          cut -d'.' -f2)
24331
24332         which fio || skip_env "no fio installed"
24333
24334         saved_debug=$($LCTL get_param -n debug)
24335         $LCTL set_param debug=0
24336
24337         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24338         ((size /= 1024)) # by megabytes
24339         ((size /= 2)) # write half of the OST at most
24340         [ $size -gt 40 ] && size=40 #reduce test time anyway
24341
24342         $LFS setstripe -c 1 $DIR/$tfile
24343
24344         # it seems like ldiskfs reserves more space than necessary if the
24345         # writing blocks are not mapped, so it extends the file firstly
24346         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24347         cancel_lru_locks osc
24348
24349         # clear and verify rpc_stats later
24350         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24351
24352         local njobs=4
24353         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24354         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24355                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24356                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24357                 --filename=$DIR/$tfile
24358         [ $? -eq 0 ] || error "fio write error"
24359
24360         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24361                 error "Locks were requested while doing AIO"
24362
24363         # get the percentage of 1-page I/O
24364         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24365                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24366                 awk '{print $7}')
24367         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24368
24369         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24370         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24371                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24372                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24373                 --filename=$DIR/$tfile
24374         [ $? -eq 0 ] || error "fio mixed read write error"
24375
24376         echo "AIO with large block size ${size}M"
24377         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24378                 --numjobs=1 --fallocate=none --ioengine=libaio \
24379                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24380                 --filename=$DIR/$tfile
24381         [ $? -eq 0 ] || error "fio large block size failed"
24382
24383         rm -f $DIR/$tfile
24384         $LCTL set_param debug="$saved_debug"
24385 }
24386 run_test 398c "run fio to test AIO"
24387
24388 test_398d() { #  LU-13846
24389         which aiocp || skip_env "no aiocp installed"
24390         local aio_file=$DIR/$tfile.aio
24391
24392         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24393
24394         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24395         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24396         stack_trap "rm -f $DIR/$tfile $aio_file"
24397
24398         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24399
24400         # make sure we don't crash and fail properly
24401         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24402                 error "aio not aligned with PAGE SIZE should fail"
24403
24404         rm -f $DIR/$tfile $aio_file
24405 }
24406 run_test 398d "run aiocp to verify block size > stripe size"
24407
24408 test_398e() {
24409         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24410         touch $DIR/$tfile.new
24411         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24412 }
24413 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24414
24415 test_398f() { #  LU-14687
24416         which aiocp || skip_env "no aiocp installed"
24417         local aio_file=$DIR/$tfile.aio
24418
24419         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24420
24421         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24422         stack_trap "rm -f $DIR/$tfile $aio_file"
24423
24424         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24425         $LCTL set_param fail_loc=0x1418
24426         # make sure we don't crash and fail properly
24427         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24428                 error "aio with page allocation failure succeeded"
24429         $LCTL set_param fail_loc=0
24430         diff $DIR/$tfile $aio_file
24431         [[ $? != 0 ]] || error "no diff after failed aiocp"
24432 }
24433 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24434
24435 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24436 # stripe and i/o size must be > stripe size
24437 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24438 # single RPC in flight.  This test shows async DIO submission is working by
24439 # showing multiple RPCs in flight.
24440 test_398g() { #  LU-13798
24441         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24442
24443         # We need to do some i/o first to acquire enough grant to put our RPCs
24444         # in flight; otherwise a new connection may not have enough grant
24445         # available
24446         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24447                 error "parallel dio failed"
24448         stack_trap "rm -f $DIR/$tfile"
24449
24450         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24451         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24452         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24453         stack_trap "$LCTL set_param -n $pages_per_rpc"
24454
24455         # Recreate file so it's empty
24456         rm -f $DIR/$tfile
24457         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24458         #Pause rpc completion to guarantee we see multiple rpcs in flight
24459         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24460         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24461         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24462
24463         # Clear rpc stats
24464         $LCTL set_param osc.*.rpc_stats=c
24465
24466         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24467                 error "parallel dio failed"
24468         stack_trap "rm -f $DIR/$tfile"
24469
24470         $LCTL get_param osc.*-OST0000-*.rpc_stats
24471         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24472                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24473                 grep "8:" | awk '{print $8}')
24474         # We look at the "8 rpcs in flight" field, and verify A) it is present
24475         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24476         # as expected for an 8M DIO to a file with 1M stripes.
24477         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24478
24479         # Verify turning off parallel dio works as expected
24480         # Clear rpc stats
24481         $LCTL set_param osc.*.rpc_stats=c
24482         $LCTL set_param llite.*.parallel_dio=0
24483         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24484
24485         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24486                 error "dio with parallel dio disabled failed"
24487
24488         # Ideally, we would see only one RPC in flight here, but there is an
24489         # unavoidable race between i/o completion and RPC in flight counting,
24490         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24491         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24492         # So instead we just verify it's always < 8.
24493         $LCTL get_param osc.*-OST0000-*.rpc_stats
24494         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24495                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24496                 grep '^$' -B1 | grep . | awk '{print $1}')
24497         [ $ret != "8:" ] ||
24498                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24499 }
24500 run_test 398g "verify parallel dio async RPC submission"
24501
24502 test_398h() { #  LU-13798
24503         local dio_file=$DIR/$tfile.dio
24504
24505         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24506
24507         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24508         stack_trap "rm -f $DIR/$tfile $dio_file"
24509
24510         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24511                 error "parallel dio failed"
24512         diff $DIR/$tfile $dio_file
24513         [[ $? == 0 ]] || error "file diff after aiocp"
24514 }
24515 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24516
24517 test_398i() { #  LU-13798
24518         local dio_file=$DIR/$tfile.dio
24519
24520         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24521
24522         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24523         stack_trap "rm -f $DIR/$tfile $dio_file"
24524
24525         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24526         $LCTL set_param fail_loc=0x1418
24527         # make sure we don't crash and fail properly
24528         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24529                 error "parallel dio page allocation failure succeeded"
24530         diff $DIR/$tfile $dio_file
24531         [[ $? != 0 ]] || error "no diff after failed aiocp"
24532 }
24533 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24534
24535 test_398j() { #  LU-13798
24536         # Stripe size > RPC size but less than i/o size tests split across
24537         # stripes and RPCs for individual i/o op
24538         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24539
24540         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24541         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24542         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24543         stack_trap "$LCTL set_param -n $pages_per_rpc"
24544
24545         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24546                 error "parallel dio write failed"
24547         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24548
24549         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24550                 error "parallel dio read failed"
24551         diff $DIR/$tfile $DIR/$tfile.2
24552         [[ $? == 0 ]] || error "file diff after parallel dio read"
24553 }
24554 run_test 398j "test parallel dio where stripe size > rpc_size"
24555
24556 test_398k() { #  LU-13798
24557         wait_delete_completed
24558         wait_mds_ost_sync
24559
24560         # 4 stripe file; we will cause out of space on OST0
24561         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24562
24563         # Fill OST0 (if it's not too large)
24564         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24565                    head -n1)
24566         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24567                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24568         fi
24569         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24570         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24571                 error "dd should fill OST0"
24572         stack_trap "rm -f $DIR/$tfile.1"
24573
24574         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24575         err=$?
24576
24577         ls -la $DIR/$tfile
24578         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24579                 error "file is not 0 bytes in size"
24580
24581         # dd above should not succeed, but don't error until here so we can
24582         # get debug info above
24583         [[ $err != 0 ]] ||
24584                 error "parallel dio write with enospc succeeded"
24585         stack_trap "rm -f $DIR/$tfile"
24586 }
24587 run_test 398k "test enospc on first stripe"
24588
24589 test_398l() { #  LU-13798
24590         wait_delete_completed
24591         wait_mds_ost_sync
24592
24593         # 4 stripe file; we will cause out of space on OST0
24594         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24595         # happens on the second i/o chunk we issue
24596         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24597
24598         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24599         stack_trap "rm -f $DIR/$tfile"
24600
24601         # Fill OST0 (if it's not too large)
24602         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24603                    head -n1)
24604         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24605                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24606         fi
24607         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24608         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24609                 error "dd should fill OST0"
24610         stack_trap "rm -f $DIR/$tfile.1"
24611
24612         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24613         err=$?
24614         stack_trap "rm -f $DIR/$tfile.2"
24615
24616         # Check that short write completed as expected
24617         ls -la $DIR/$tfile.2
24618         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24619                 error "file is not 1M in size"
24620
24621         # dd above should not succeed, but don't error until here so we can
24622         # get debug info above
24623         [[ $err != 0 ]] ||
24624                 error "parallel dio write with enospc succeeded"
24625
24626         # Truncate source file to same length as output file and diff them
24627         $TRUNCATE $DIR/$tfile 1048576
24628         diff $DIR/$tfile $DIR/$tfile.2
24629         [[ $? == 0 ]] || error "data incorrect after short write"
24630 }
24631 run_test 398l "test enospc on intermediate stripe/RPC"
24632
24633 test_398m() { #  LU-13798
24634         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24635
24636         # Set up failure on OST0, the first stripe:
24637         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24638         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24639         # So this fail_val specifies OST0
24640         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24641         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24642
24643         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24644                 error "parallel dio write with failure on first stripe succeeded"
24645         stack_trap "rm -f $DIR/$tfile"
24646         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24647
24648         # Place data in file for read
24649         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24650                 error "parallel dio write failed"
24651
24652         # Fail read on OST0, first stripe
24653         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24654         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24655         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24656                 error "parallel dio read with error on first stripe succeeded"
24657         rm -f $DIR/$tfile.2
24658         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24659
24660         # Switch to testing on OST1, second stripe
24661         # Clear file contents, maintain striping
24662         echo > $DIR/$tfile
24663         # Set up failure on OST1, second stripe:
24664         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24665         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24666
24667         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24668                 error "parallel dio write with failure on first stripe succeeded"
24669         stack_trap "rm -f $DIR/$tfile"
24670         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24671
24672         # Place data in file for read
24673         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24674                 error "parallel dio write failed"
24675
24676         # Fail read on OST1, second stripe
24677         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24678         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24679         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24680                 error "parallel dio read with error on first stripe succeeded"
24681         rm -f $DIR/$tfile.2
24682         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24683 }
24684 run_test 398m "test RPC failures with parallel dio"
24685
24686 # Parallel submission of DIO should not cause problems for append, but it's
24687 # important to verify.
24688 test_398n() { #  LU-13798
24689         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24690
24691         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24692                 error "dd to create source file failed"
24693         stack_trap "rm -f $DIR/$tfile"
24694
24695         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24696                 error "parallel dio write with failure on second stripe succeeded"
24697         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24698         diff $DIR/$tfile $DIR/$tfile.1
24699         [[ $? == 0 ]] || error "data incorrect after append"
24700
24701 }
24702 run_test 398n "test append with parallel DIO"
24703
24704 test_fake_rw() {
24705         local read_write=$1
24706         if [ "$read_write" = "write" ]; then
24707                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24708         elif [ "$read_write" = "read" ]; then
24709                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24710         else
24711                 error "argument error"
24712         fi
24713
24714         # turn off debug for performance testing
24715         local saved_debug=$($LCTL get_param -n debug)
24716         $LCTL set_param debug=0
24717
24718         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24719
24720         # get ost1 size - $FSNAME-OST0000
24721         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24722         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24723         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24724
24725         if [ "$read_write" = "read" ]; then
24726                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24727         fi
24728
24729         local start_time=$(date +%s.%N)
24730         $dd_cmd bs=1M count=$blocks oflag=sync ||
24731                 error "real dd $read_write error"
24732         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24733
24734         if [ "$read_write" = "write" ]; then
24735                 rm -f $DIR/$tfile
24736         fi
24737
24738         # define OBD_FAIL_OST_FAKE_RW           0x238
24739         do_facet ost1 $LCTL set_param fail_loc=0x238
24740
24741         local start_time=$(date +%s.%N)
24742         $dd_cmd bs=1M count=$blocks oflag=sync ||
24743                 error "fake dd $read_write error"
24744         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24745
24746         if [ "$read_write" = "write" ]; then
24747                 # verify file size
24748                 cancel_lru_locks osc
24749                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24750                         error "$tfile size not $blocks MB"
24751         fi
24752         do_facet ost1 $LCTL set_param fail_loc=0
24753
24754         echo "fake $read_write $duration_fake vs. normal $read_write" \
24755                 "$duration in seconds"
24756         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24757                 error_not_in_vm "fake write is slower"
24758
24759         $LCTL set_param -n debug="$saved_debug"
24760         rm -f $DIR/$tfile
24761 }
24762 test_399a() { # LU-7655 for OST fake write
24763         remote_ost_nodsh && skip "remote OST with nodsh"
24764
24765         test_fake_rw write
24766 }
24767 run_test 399a "fake write should not be slower than normal write"
24768
24769 test_399b() { # LU-8726 for OST fake read
24770         remote_ost_nodsh && skip "remote OST with nodsh"
24771         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24772                 skip_env "ldiskfs only test"
24773         fi
24774
24775         test_fake_rw read
24776 }
24777 run_test 399b "fake read should not be slower than normal read"
24778
24779 test_400a() { # LU-1606, was conf-sanity test_74
24780         if ! which $CC > /dev/null 2>&1; then
24781                 skip_env "$CC is not installed"
24782         fi
24783
24784         local extra_flags=''
24785         local out=$TMP/$tfile
24786         local prefix=/usr/include/lustre
24787         local prog
24788
24789         # Oleg removes c files in his test rig so test if any c files exist
24790         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24791                 skip_env "Needed c test files are missing"
24792
24793         if ! [[ -d $prefix ]]; then
24794                 # Assume we're running in tree and fixup the include path.
24795                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24796                 extra_flags+=" -L$LUSTRE/utils/.lib"
24797         fi
24798
24799         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24800                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24801                         error "client api broken"
24802         done
24803         rm -f $out
24804 }
24805 run_test 400a "Lustre client api program can compile and link"
24806
24807 test_400b() { # LU-1606, LU-5011
24808         local header
24809         local out=$TMP/$tfile
24810         local prefix=/usr/include/linux/lustre
24811
24812         # We use a hard coded prefix so that this test will not fail
24813         # when run in tree. There are headers in lustre/include/lustre/
24814         # that are not packaged (like lustre_idl.h) and have more
24815         # complicated include dependencies (like config.h and lnet/types.h).
24816         # Since this test about correct packaging we just skip them when
24817         # they don't exist (see below) rather than try to fixup cppflags.
24818
24819         if ! which $CC > /dev/null 2>&1; then
24820                 skip_env "$CC is not installed"
24821         fi
24822
24823         for header in $prefix/*.h; do
24824                 if ! [[ -f "$header" ]]; then
24825                         continue
24826                 fi
24827
24828                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24829                         continue # lustre_ioctl.h is internal header
24830                 fi
24831
24832                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24833                         error "cannot compile '$header'"
24834         done
24835         rm -f $out
24836 }
24837 run_test 400b "packaged headers can be compiled"
24838
24839 test_401a() { #LU-7437
24840         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24841         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24842
24843         #count the number of parameters by "list_param -R"
24844         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24845         #count the number of parameters by listing proc files
24846         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24847         echo "proc_dirs='$proc_dirs'"
24848         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24849         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24850                       sort -u | wc -l)
24851
24852         [ $params -eq $procs ] ||
24853                 error "found $params parameters vs. $procs proc files"
24854
24855         # test the list_param -D option only returns directories
24856         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24857         #count the number of parameters by listing proc directories
24858         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24859                 sort -u | wc -l)
24860
24861         [ $params -eq $procs ] ||
24862                 error "found $params parameters vs. $procs proc files"
24863 }
24864 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24865
24866 test_401b() {
24867         # jobid_var may not allow arbitrary values, so use jobid_name
24868         # if available
24869         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24870                 local testname=jobid_name tmp='testing%p'
24871         else
24872                 local testname=jobid_var tmp=testing
24873         fi
24874
24875         local save=$($LCTL get_param -n $testname)
24876
24877         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24878                 error "no error returned when setting bad parameters"
24879
24880         local jobid_new=$($LCTL get_param -n foe $testname baz)
24881         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24882
24883         $LCTL set_param -n fog=bam $testname=$save bat=fog
24884         local jobid_old=$($LCTL get_param -n foe $testname bag)
24885         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24886 }
24887 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24888
24889 test_401c() {
24890         # jobid_var may not allow arbitrary values, so use jobid_name
24891         # if available
24892         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24893                 local testname=jobid_name
24894         else
24895                 local testname=jobid_var
24896         fi
24897
24898         local jobid_var_old=$($LCTL get_param -n $testname)
24899         local jobid_var_new
24900
24901         $LCTL set_param $testname= &&
24902                 error "no error returned for 'set_param a='"
24903
24904         jobid_var_new=$($LCTL get_param -n $testname)
24905         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24906                 error "$testname was changed by setting without value"
24907
24908         $LCTL set_param $testname &&
24909                 error "no error returned for 'set_param a'"
24910
24911         jobid_var_new=$($LCTL get_param -n $testname)
24912         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24913                 error "$testname was changed by setting without value"
24914 }
24915 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24916
24917 test_401d() {
24918         # jobid_var may not allow arbitrary values, so use jobid_name
24919         # if available
24920         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24921                 local testname=jobid_name new_value='foo=bar%p'
24922         else
24923                 local testname=jobid_var new_valuie=foo=bar
24924         fi
24925
24926         local jobid_var_old=$($LCTL get_param -n $testname)
24927         local jobid_var_new
24928
24929         $LCTL set_param $testname=$new_value ||
24930                 error "'set_param a=b' did not accept a value containing '='"
24931
24932         jobid_var_new=$($LCTL get_param -n $testname)
24933         [[ "$jobid_var_new" == "$new_value" ]] ||
24934                 error "'set_param a=b' failed on a value containing '='"
24935
24936         # Reset the $testname to test the other format
24937         $LCTL set_param $testname=$jobid_var_old
24938         jobid_var_new=$($LCTL get_param -n $testname)
24939         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24940                 error "failed to reset $testname"
24941
24942         $LCTL set_param $testname $new_value ||
24943                 error "'set_param a b' did not accept a value containing '='"
24944
24945         jobid_var_new=$($LCTL get_param -n $testname)
24946         [[ "$jobid_var_new" == "$new_value" ]] ||
24947                 error "'set_param a b' failed on a value containing '='"
24948
24949         $LCTL set_param $testname $jobid_var_old
24950         jobid_var_new=$($LCTL get_param -n $testname)
24951         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24952                 error "failed to reset $testname"
24953 }
24954 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24955
24956 test_401e() { # LU-14779
24957         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24958                 error "lctl list_param MGC* failed"
24959         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24960         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24961                 error "lctl get_param lru_size failed"
24962 }
24963 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24964
24965 test_402() {
24966         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24967         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24968                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24969         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24970                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24971                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24972         remote_mds_nodsh && skip "remote MDS with nodsh"
24973
24974         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24975 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24976         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24977         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24978                 echo "Touch failed - OK"
24979 }
24980 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24981
24982 test_403() {
24983         local file1=$DIR/$tfile.1
24984         local file2=$DIR/$tfile.2
24985         local tfile=$TMP/$tfile
24986
24987         rm -f $file1 $file2 $tfile
24988
24989         touch $file1
24990         ln $file1 $file2
24991
24992         # 30 sec OBD_TIMEOUT in ll_getattr()
24993         # right before populating st_nlink
24994         $LCTL set_param fail_loc=0x80001409
24995         stat -c %h $file1 > $tfile &
24996
24997         # create an alias, drop all locks and reclaim the dentry
24998         < $file2
24999         cancel_lru_locks mdc
25000         cancel_lru_locks osc
25001         sysctl -w vm.drop_caches=2
25002
25003         wait
25004
25005         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25006
25007         rm -f $tfile $file1 $file2
25008 }
25009 run_test 403 "i_nlink should not drop to zero due to aliasing"
25010
25011 test_404() { # LU-6601
25012         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25013                 skip "Need server version newer than 2.8.52"
25014         remote_mds_nodsh && skip "remote MDS with nodsh"
25015
25016         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25017                 awk '/osp .*-osc-MDT/ { print $4}')
25018
25019         local osp
25020         for osp in $mosps; do
25021                 echo "Deactivate: " $osp
25022                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25023                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25024                         awk -vp=$osp '$4 == p { print $2 }')
25025                 [ $stat = IN ] || {
25026                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25027                         error "deactivate error"
25028                 }
25029                 echo "Activate: " $osp
25030                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25031                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25032                         awk -vp=$osp '$4 == p { print $2 }')
25033                 [ $stat = UP ] || {
25034                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25035                         error "activate error"
25036                 }
25037         done
25038 }
25039 run_test 404 "validate manual {de}activated works properly for OSPs"
25040
25041 test_405() {
25042         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25043         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25044                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25045                         skip "Layout swap lock is not supported"
25046
25047         check_swap_layouts_support
25048         check_swap_layout_no_dom $DIR
25049
25050         test_mkdir $DIR/$tdir
25051         swap_lock_test -d $DIR/$tdir ||
25052                 error "One layout swap locked test failed"
25053 }
25054 run_test 405 "Various layout swap lock tests"
25055
25056 test_406() {
25057         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25058         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25059         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25061         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25062                 skip "Need MDS version at least 2.8.50"
25063
25064         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25065         local test_pool=$TESTNAME
25066
25067         pool_add $test_pool || error "pool_add failed"
25068         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25069                 error "pool_add_targets failed"
25070
25071         save_layout_restore_at_exit $MOUNT
25072
25073         # parent set default stripe count only, child will stripe from both
25074         # parent and fs default
25075         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25076                 error "setstripe $MOUNT failed"
25077         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25078         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25079         for i in $(seq 10); do
25080                 local f=$DIR/$tdir/$tfile.$i
25081                 touch $f || error "touch failed"
25082                 local count=$($LFS getstripe -c $f)
25083                 [ $count -eq $OSTCOUNT ] ||
25084                         error "$f stripe count $count != $OSTCOUNT"
25085                 local offset=$($LFS getstripe -i $f)
25086                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25087                 local size=$($LFS getstripe -S $f)
25088                 [ $size -eq $((def_stripe_size * 2)) ] ||
25089                         error "$f stripe size $size != $((def_stripe_size * 2))"
25090                 local pool=$($LFS getstripe -p $f)
25091                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25092         done
25093
25094         # change fs default striping, delete parent default striping, now child
25095         # will stripe from new fs default striping only
25096         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25097                 error "change $MOUNT default stripe failed"
25098         $LFS setstripe -c 0 $DIR/$tdir ||
25099                 error "delete $tdir default stripe failed"
25100         for i in $(seq 11 20); do
25101                 local f=$DIR/$tdir/$tfile.$i
25102                 touch $f || error "touch $f failed"
25103                 local count=$($LFS getstripe -c $f)
25104                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25105                 local offset=$($LFS getstripe -i $f)
25106                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25107                 local size=$($LFS getstripe -S $f)
25108                 [ $size -eq $def_stripe_size ] ||
25109                         error "$f stripe size $size != $def_stripe_size"
25110                 local pool=$($LFS getstripe -p $f)
25111                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25112         done
25113
25114         unlinkmany $DIR/$tdir/$tfile. 1 20
25115
25116         local f=$DIR/$tdir/$tfile
25117         pool_remove_all_targets $test_pool $f
25118         pool_remove $test_pool $f
25119 }
25120 run_test 406 "DNE support fs default striping"
25121
25122 test_407() {
25123         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25124         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25125                 skip "Need MDS version at least 2.8.55"
25126         remote_mds_nodsh && skip "remote MDS with nodsh"
25127
25128         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25129                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25130         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25131                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25132         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25133
25134         #define OBD_FAIL_DT_TXN_STOP    0x2019
25135         for idx in $(seq $MDSCOUNT); do
25136                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25137         done
25138         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25139         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25140                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25141         true
25142 }
25143 run_test 407 "transaction fail should cause operation fail"
25144
25145 test_408() {
25146         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25147
25148         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25149         lctl set_param fail_loc=0x8000040a
25150         # let ll_prepare_partial_page() fail
25151         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25152
25153         rm -f $DIR/$tfile
25154
25155         # create at least 100 unused inodes so that
25156         # shrink_icache_memory(0) should not return 0
25157         touch $DIR/$tfile-{0..100}
25158         rm -f $DIR/$tfile-{0..100}
25159         sync
25160
25161         echo 2 > /proc/sys/vm/drop_caches
25162 }
25163 run_test 408 "drop_caches should not hang due to page leaks"
25164
25165 test_409()
25166 {
25167         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25168
25169         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25170         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25171         touch $DIR/$tdir/guard || error "(2) Fail to create"
25172
25173         local PREFIX=$(str_repeat 'A' 128)
25174         echo "Create 1K hard links start at $(date)"
25175         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25176                 error "(3) Fail to hard link"
25177
25178         echo "Links count should be right although linkEA overflow"
25179         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25180         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25181         [ $linkcount -eq 1001 ] ||
25182                 error "(5) Unexpected hard links count: $linkcount"
25183
25184         echo "List all links start at $(date)"
25185         ls -l $DIR/$tdir/foo > /dev/null ||
25186                 error "(6) Fail to list $DIR/$tdir/foo"
25187
25188         echo "Unlink hard links start at $(date)"
25189         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25190                 error "(7) Fail to unlink"
25191         echo "Unlink hard links finished at $(date)"
25192 }
25193 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25194
25195 test_410()
25196 {
25197         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25198                 skip "Need client version at least 2.9.59"
25199         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25200                 skip "Need MODULES build"
25201
25202         # Create a file, and stat it from the kernel
25203         local testfile=$DIR/$tfile
25204         touch $testfile
25205
25206         local run_id=$RANDOM
25207         local my_ino=$(stat --format "%i" $testfile)
25208
25209         # Try to insert the module. This will always fail as the
25210         # module is designed to not be inserted.
25211         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25212             &> /dev/null
25213
25214         # Anything but success is a test failure
25215         dmesg | grep -q \
25216             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25217             error "no inode match"
25218 }
25219 run_test 410 "Test inode number returned from kernel thread"
25220
25221 cleanup_test411_cgroup() {
25222         trap 0
25223         rmdir "$1"
25224 }
25225
25226 test_411() {
25227         local cg_basedir=/sys/fs/cgroup/memory
25228         # LU-9966
25229         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25230                 skip "no setup for cgroup"
25231
25232         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25233                 error "test file creation failed"
25234         cancel_lru_locks osc
25235
25236         # Create a very small memory cgroup to force a slab allocation error
25237         local cgdir=$cg_basedir/osc_slab_alloc
25238         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25239         trap "cleanup_test411_cgroup $cgdir" EXIT
25240         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25241         echo 1M > $cgdir/memory.limit_in_bytes
25242
25243         # Should not LBUG, just be killed by oom-killer
25244         # dd will return 0 even allocation failure in some environment.
25245         # So don't check return value
25246         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25247         cleanup_test411_cgroup $cgdir
25248
25249         return 0
25250 }
25251 run_test 411 "Slab allocation error with cgroup does not LBUG"
25252
25253 test_412() {
25254         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25255         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25256                 skip "Need server version at least 2.10.55"
25257
25258         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25259                 error "mkdir failed"
25260         $LFS getdirstripe $DIR/$tdir
25261         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25262         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25263                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25264         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25265         [ $stripe_count -eq 2 ] ||
25266                 error "expect 2 get $stripe_count"
25267
25268         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25269
25270         local index
25271         local index2
25272
25273         # subdirs should be on the same MDT as parent
25274         for i in $(seq 0 $((MDSCOUNT - 1))); do
25275                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25276                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25277                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25278                 (( index == i )) || error "mdt$i/sub on MDT$index"
25279         done
25280
25281         # stripe offset -1, ditto
25282         for i in {1..10}; do
25283                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25284                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25285                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25286                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25287                 (( index == index2 )) ||
25288                         error "qos$i on MDT$index, sub on MDT$index2"
25289         done
25290
25291         local testdir=$DIR/$tdir/inherit
25292
25293         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25294         # inherit 2 levels
25295         for i in 1 2; do
25296                 testdir=$testdir/s$i
25297                 mkdir $testdir || error "mkdir $testdir failed"
25298                 index=$($LFS getstripe -m $testdir)
25299                 (( index == 1 )) ||
25300                         error "$testdir on MDT$index"
25301         done
25302
25303         # not inherit any more
25304         testdir=$testdir/s3
25305         mkdir $testdir || error "mkdir $testdir failed"
25306         getfattr -d -m dmv $testdir | grep dmv &&
25307                 error "default LMV set on $testdir" || true
25308 }
25309 run_test 412 "mkdir on specific MDTs"
25310
25311 generate_uneven_mdts() {
25312         local threshold=$1
25313         local lmv_qos_maxage
25314         local lod_qos_maxage
25315         local ffree
25316         local bavail
25317         local max
25318         local min
25319         local max_index
25320         local min_index
25321         local tmp
25322         local i
25323
25324         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25325         $LCTL set_param lmv.*.qos_maxage=1
25326         stack_trap "$LCTL set_param \
25327                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25328         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25329                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25330         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25331                 lod.*.mdt_qos_maxage=1
25332         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25333                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25334
25335         echo
25336         echo "Check for uneven MDTs: "
25337
25338         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25339         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25340         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25341
25342         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25343         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25344         max_index=0
25345         min_index=0
25346         for ((i = 1; i < ${#ffree[@]}; i++)); do
25347                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25348                 if [ $tmp -gt $max ]; then
25349                         max=$tmp
25350                         max_index=$i
25351                 fi
25352                 if [ $tmp -lt $min ]; then
25353                         min=$tmp
25354                         min_index=$i
25355                 fi
25356         done
25357
25358         (( ${ffree[min_index]} > 0 )) ||
25359                 skip "no free files in MDT$min_index"
25360         (( ${ffree[min_index]} < 10000000 )) ||
25361                 skip "too many free files in MDT$min_index"
25362
25363         # Check if we need to generate uneven MDTs
25364         local diff=$(((max - min) * 100 / min))
25365         local testdir=$DIR/$tdir-fillmdt
25366         local start
25367
25368         mkdir -p $testdir
25369
25370         i=0
25371         while (( diff < threshold )); do
25372                 # generate uneven MDTs, create till $threshold% diff
25373                 echo -n "weight diff=$diff% must be > $threshold% ..."
25374                 echo "Fill MDT$min_index with 1000 files: loop $i"
25375                 testdir=$DIR/$tdir-fillmdt/$i
25376                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25377                         error "mkdir $testdir failed"
25378                 $LFS setstripe -E 1M -L mdt $testdir ||
25379                         error "setstripe $testdir failed"
25380                 start=$SECONDS
25381                 for F in f.{0..999}; do
25382                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25383                                 /dev/null 2>&1 || error "dd $F failed"
25384                 done
25385
25386                 # wait for QOS to update
25387                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25388
25389                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25390                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25391                 max=$(((${ffree[max_index]} >> 8) *
25392                         (${bavail[max_index]} * bsize >> 16)))
25393                 min=$(((${ffree[min_index]} >> 8) *
25394                         (${bavail[min_index]} * bsize >> 16)))
25395                 diff=$(((max - min) * 100 / min))
25396                 i=$((i + 1))
25397         done
25398
25399         echo "MDT filesfree available: ${ffree[*]}"
25400         echo "MDT blocks available: ${bavail[*]}"
25401         echo "weight diff=$diff%"
25402 }
25403
25404 test_qos_mkdir() {
25405         local mkdir_cmd=$1
25406         local stripe_count=$2
25407         local mdts=$(comma_list $(mdts_nodes))
25408
25409         local testdir
25410         local lmv_qos_prio_free
25411         local lmv_qos_threshold_rr
25412         local lmv_qos_maxage
25413         local lod_qos_prio_free
25414         local lod_qos_threshold_rr
25415         local lod_qos_maxage
25416         local count
25417         local i
25418
25419         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25420         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25421         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25422                 head -n1)
25423         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25424         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25425         stack_trap "$LCTL set_param \
25426                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25427         stack_trap "$LCTL set_param \
25428                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25429         stack_trap "$LCTL set_param \
25430                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25431
25432         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25433                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25434         lod_qos_prio_free=${lod_qos_prio_free%%%}
25435         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25436                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25437         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25438         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25439                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25440         stack_trap "do_nodes $mdts $LCTL set_param \
25441                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25442         stack_trap "do_nodes $mdts $LCTL set_param \
25443                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25444         stack_trap "do_nodes $mdts $LCTL set_param \
25445                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25446
25447         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25448         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25449
25450         testdir=$DIR/$tdir-s$stripe_count/rr
25451
25452         local stripe_index=$($LFS getstripe -m $testdir)
25453         local test_mkdir_rr=true
25454
25455         getfattr -d -m dmv -e hex $testdir | grep dmv
25456         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25457                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25458                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25459                         test_mkdir_rr=false
25460         fi
25461
25462         echo
25463         $test_mkdir_rr &&
25464                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25465                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25466
25467         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25468         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25469                 eval $mkdir_cmd $testdir/subdir$i ||
25470                         error "$mkdir_cmd subdir$i failed"
25471         done
25472
25473         for (( i = 0; i < $MDSCOUNT; i++ )); do
25474                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25475                 echo "$count directories created on MDT$i"
25476                 if $test_mkdir_rr; then
25477                         (( $count == 100 )) ||
25478                                 error "subdirs are not evenly distributed"
25479                 elif (( $i == $stripe_index )); then
25480                         (( $count == 100 * MDSCOUNT )) ||
25481                                 error "$count subdirs created on MDT$i"
25482                 else
25483                         (( $count == 0 )) ||
25484                                 error "$count subdirs created on MDT$i"
25485                 fi
25486
25487                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25488                         count=$($LFS getdirstripe $testdir/* |
25489                                 grep -c -P "^\s+$i\t")
25490                         echo "$count stripes created on MDT$i"
25491                         # deviation should < 5% of average
25492                         (( $count >= 95 * stripe_count &&
25493                            $count <= 105 * stripe_count)) ||
25494                                 error "stripes are not evenly distributed"
25495                 fi
25496         done
25497
25498         echo
25499         echo "Check for uneven MDTs: "
25500
25501         local ffree
25502         local bavail
25503         local max
25504         local min
25505         local max_index
25506         local min_index
25507         local tmp
25508
25509         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25510         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25511         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25512
25513         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25514         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25515         max_index=0
25516         min_index=0
25517         for ((i = 1; i < ${#ffree[@]}; i++)); do
25518                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25519                 if [ $tmp -gt $max ]; then
25520                         max=$tmp
25521                         max_index=$i
25522                 fi
25523                 if [ $tmp -lt $min ]; then
25524                         min=$tmp
25525                         min_index=$i
25526                 fi
25527         done
25528
25529         (( ${ffree[min_index]} > 0 )) ||
25530                 skip "no free files in MDT$min_index"
25531         (( ${ffree[min_index]} < 10000000 )) ||
25532                 skip "too many free files in MDT$min_index"
25533
25534         echo "MDT filesfree available: ${ffree[*]}"
25535         echo "MDT blocks available: ${bavail[*]}"
25536         echo "weight diff=$(((max - min) * 100 / min))%"
25537         echo
25538         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25539
25540         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25541         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25542         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25543         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25544         # decrease statfs age, so that it can be updated in time
25545         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25546         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25547
25548         sleep 1
25549
25550         testdir=$DIR/$tdir-s$stripe_count/qos
25551         local num=200
25552
25553         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25554         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25555                 eval $mkdir_cmd $testdir/subdir$i ||
25556                         error "$mkdir_cmd subdir$i failed"
25557         done
25558
25559         max=0
25560         for (( i = 0; i < $MDSCOUNT; i++ )); do
25561                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25562                 (( count > max )) && max=$count
25563                 echo "$count directories created on MDT$i"
25564         done
25565
25566         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25567
25568         # D-value should > 10% of averge
25569         (( max - min > num / 10 )) ||
25570                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25571
25572         # ditto for stripes
25573         if (( stripe_count > 1 )); then
25574                 max=0
25575                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25576                         count=$($LFS getdirstripe $testdir/* |
25577                                 grep -c -P "^\s+$i\t")
25578                         (( count > max )) && max=$count
25579                         echo "$count stripes created on MDT$i"
25580                 done
25581
25582                 min=$($LFS getdirstripe $testdir/* |
25583                         grep -c -P "^\s+$min_index\t")
25584                 (( max - min > num * stripe_count / 10 )) ||
25585                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25586         fi
25587 }
25588
25589 most_full_mdt() {
25590         local ffree
25591         local bavail
25592         local bsize
25593         local min
25594         local min_index
25595         local tmp
25596
25597         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25598         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25599         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25600
25601         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25602         min_index=0
25603         for ((i = 1; i < ${#ffree[@]}; i++)); do
25604                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25605                 (( tmp < min )) && min=$tmp && min_index=$i
25606         done
25607
25608         echo -n $min_index
25609 }
25610
25611 test_413a() {
25612         [ $MDSCOUNT -lt 2 ] &&
25613                 skip "We need at least 2 MDTs for this test"
25614
25615         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25616                 skip "Need server version at least 2.12.52"
25617
25618         local stripe_count
25619
25620         generate_uneven_mdts 100
25621         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25622                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25623                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25624                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25625                         error "mkdir failed"
25626                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25627         done
25628 }
25629 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25630
25631 test_413b() {
25632         [ $MDSCOUNT -lt 2 ] &&
25633                 skip "We need at least 2 MDTs for this test"
25634
25635         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25636                 skip "Need server version at least 2.12.52"
25637
25638         local testdir
25639         local stripe_count
25640
25641         generate_uneven_mdts 100
25642         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25643                 testdir=$DIR/$tdir-s$stripe_count
25644                 mkdir $testdir || error "mkdir $testdir failed"
25645                 mkdir $testdir/rr || error "mkdir rr failed"
25646                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25647                         error "mkdir qos failed"
25648                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25649                         $testdir/rr || error "setdirstripe rr failed"
25650                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25651                         error "setdirstripe failed"
25652                 test_qos_mkdir "mkdir" $stripe_count
25653         done
25654 }
25655 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25656
25657 test_413c() {
25658         (( $MDSCOUNT >= 2 )) ||
25659                 skip "We need at least 2 MDTs for this test"
25660
25661         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25662                 skip "Need server version at least 2.14.51"
25663
25664         local testdir
25665         local inherit
25666         local inherit_rr
25667
25668         testdir=$DIR/${tdir}-s1
25669         mkdir $testdir || error "mkdir $testdir failed"
25670         mkdir $testdir/rr || error "mkdir rr failed"
25671         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25672         # default max_inherit is -1, default max_inherit_rr is 0
25673         $LFS setdirstripe -D -c 1 $testdir/rr ||
25674                 error "setdirstripe rr failed"
25675         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25676                 error "setdirstripe qos failed"
25677         test_qos_mkdir "mkdir" 1
25678
25679         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25680         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25681         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25682         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25683         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25684
25685         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25686         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25687         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25688         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25689         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25690         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25691         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25692                 error "level2 shouldn't have default LMV" || true
25693 }
25694 run_test 413c "mkdir with default LMV max inherit rr"
25695
25696 test_413d() {
25697         (( MDSCOUNT >= 2 )) ||
25698                 skip "We need at least 2 MDTs for this test"
25699
25700         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25701                 skip "Need server version at least 2.14.51"
25702
25703         local lmv_qos_threshold_rr
25704
25705         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25706                 head -n1)
25707         stack_trap "$LCTL set_param \
25708                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25709
25710         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25711         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25712         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25713                 error "$tdir shouldn't have default LMV"
25714         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25715                 error "mkdir sub failed"
25716
25717         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25718
25719         (( count == 100 )) || error "$count subdirs on MDT0"
25720 }
25721 run_test 413d "inherit ROOT default LMV"
25722
25723 test_413e() {
25724         (( MDSCOUNT >= 2 )) ||
25725                 skip "We need at least 2 MDTs for this test"
25726         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25727                 skip "Need server version at least 2.14.55"
25728
25729         local testdir=$DIR/$tdir
25730         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25731         local max_inherit
25732         local sub_max_inherit
25733
25734         mkdir -p $testdir || error "failed to create $testdir"
25735
25736         # set default max-inherit to -1 if stripe count is 0 or 1
25737         $LFS setdirstripe -D -c 1 $testdir ||
25738                 error "failed to set default LMV"
25739         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25740         (( max_inherit == -1 )) ||
25741                 error "wrong max_inherit value $max_inherit"
25742
25743         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25744         $LFS setdirstripe -D -c -1 $testdir ||
25745                 error "failed to set default LMV"
25746         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25747         (( max_inherit > 0 )) ||
25748                 error "wrong max_inherit value $max_inherit"
25749
25750         # and the subdir will decrease the max_inherit by 1
25751         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25752         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25753         (( sub_max_inherit == max_inherit - 1)) ||
25754                 error "wrong max-inherit of subdir $sub_max_inherit"
25755
25756         # check specified --max-inherit and warning message
25757         stack_trap "rm -f $tmpfile"
25758         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25759                 error "failed to set default LMV"
25760         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25761         (( max_inherit == -1 )) ||
25762                 error "wrong max_inherit value $max_inherit"
25763
25764         # check the warning messages
25765         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25766                 error "failed to detect warning string"
25767         fi
25768 }
25769 run_test 413e "check default max-inherit value"
25770
25771 test_413f() {
25772         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25773
25774         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25775                 skip "Need server version at least 2.14.55"
25776
25777         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25778                 error "dump $DIR default LMV failed"
25779         stack_trap "setfattr --restore=$TMP/dmv.ea"
25780
25781         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25782                 error "set $DIR default LMV failed"
25783
25784         local testdir=$DIR/$tdir
25785
25786         local count
25787         local inherit
25788         local inherit_rr
25789
25790         for i in $(seq 3); do
25791                 mkdir $testdir || error "mkdir $testdir failed"
25792                 count=$($LFS getdirstripe -D -c $testdir)
25793                 (( count == 1 )) ||
25794                         error "$testdir default LMV count mismatch $count != 1"
25795                 inherit=$($LFS getdirstripe -D -X $testdir)
25796                 (( inherit == 3 - i )) ||
25797                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25798                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25799                 (( inherit_rr == 3 - i )) ||
25800                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25801                 testdir=$testdir/sub
25802         done
25803
25804         mkdir $testdir || error "mkdir $testdir failed"
25805         count=$($LFS getdirstripe -D -c $testdir)
25806         (( count == 0 )) ||
25807                 error "$testdir default LMV count not zero: $count"
25808 }
25809 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25810
25811 test_413z() {
25812         local pids=""
25813         local subdir
25814         local pid
25815
25816         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25817                 unlinkmany $subdir/f. 1000 &
25818                 pids="$pids $!"
25819         done
25820
25821         for pid in $pids; do
25822                 wait $pid
25823         done
25824 }
25825 run_test 413z "413 test cleanup"
25826
25827 test_414() {
25828 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25829         $LCTL set_param fail_loc=0x80000521
25830         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25831         rm -f $DIR/$tfile
25832 }
25833 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25834
25835 test_415() {
25836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25837         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25838                 skip "Need server version at least 2.11.52"
25839
25840         # LU-11102
25841         local total
25842         local setattr_pid
25843         local start_time
25844         local end_time
25845         local duration
25846
25847         total=500
25848         # this test may be slow on ZFS
25849         [ "$mds1_FSTYPE" == "zfs" ] && total=50
25850
25851         # though this test is designed for striped directory, let's test normal
25852         # directory too since lock is always saved as CoS lock.
25853         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25854         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25855
25856         (
25857                 while true; do
25858                         touch $DIR/$tdir
25859                 done
25860         ) &
25861         setattr_pid=$!
25862
25863         start_time=$(date +%s)
25864         for i in $(seq $total); do
25865                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25866                         > /dev/null
25867         done
25868         end_time=$(date +%s)
25869         duration=$((end_time - start_time))
25870
25871         kill -9 $setattr_pid
25872
25873         echo "rename $total files took $duration sec"
25874         [ $duration -lt 100 ] || error "rename took $duration sec"
25875 }
25876 run_test 415 "lock revoke is not missing"
25877
25878 test_416() {
25879         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25880                 skip "Need server version at least 2.11.55"
25881
25882         # define OBD_FAIL_OSD_TXN_START    0x19a
25883         do_facet mds1 lctl set_param fail_loc=0x19a
25884
25885         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25886
25887         true
25888 }
25889 run_test 416 "transaction start failure won't cause system hung"
25890
25891 cleanup_417() {
25892         trap 0
25893         do_nodes $(comma_list $(mdts_nodes)) \
25894                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25895         do_nodes $(comma_list $(mdts_nodes)) \
25896                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25897         do_nodes $(comma_list $(mdts_nodes)) \
25898                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25899 }
25900
25901 test_417() {
25902         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25903         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25904                 skip "Need MDS version at least 2.11.56"
25905
25906         trap cleanup_417 RETURN EXIT
25907
25908         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25909         do_nodes $(comma_list $(mdts_nodes)) \
25910                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25911         $LFS migrate -m 0 $DIR/$tdir.1 &&
25912                 error "migrate dir $tdir.1 should fail"
25913
25914         do_nodes $(comma_list $(mdts_nodes)) \
25915                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25916         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25917                 error "create remote dir $tdir.2 should fail"
25918
25919         do_nodes $(comma_list $(mdts_nodes)) \
25920                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25921         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25922                 error "create striped dir $tdir.3 should fail"
25923         true
25924 }
25925 run_test 417 "disable remote dir, striped dir and dir migration"
25926
25927 # Checks that the outputs of df [-i] and lfs df [-i] match
25928 #
25929 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25930 check_lfs_df() {
25931         local dir=$2
25932         local inodes
25933         local df_out
25934         local lfs_df_out
25935         local count
25936         local passed=false
25937
25938         # blocks or inodes
25939         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25940
25941         for count in {1..100}; do
25942                 do_nodes "$CLIENTS" \
25943                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25944                 sync; sleep 0.2
25945
25946                 # read the lines of interest
25947                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25948                         error "df $inodes $dir | tail -n +2 failed"
25949                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25950                         error "lfs df $inodes $dir | grep summary: failed"
25951
25952                 # skip first substrings of each output as they are different
25953                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25954                 # compare the two outputs
25955                 passed=true
25956                 #  skip "available" on MDT until LU-13997 is fixed.
25957                 #for i in {1..5}; do
25958                 for i in 1 2 4 5; do
25959                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25960                 done
25961                 $passed && break
25962         done
25963
25964         if ! $passed; then
25965                 df -P $inodes $dir
25966                 echo
25967                 lfs df $inodes $dir
25968                 error "df and lfs df $1 output mismatch: "      \
25969                       "df ${inodes}: ${df_out[*]}, "            \
25970                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25971         fi
25972 }
25973
25974 test_418() {
25975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25976
25977         local dir=$DIR/$tdir
25978         local numfiles=$((RANDOM % 4096 + 2))
25979         local numblocks=$((RANDOM % 256 + 1))
25980
25981         wait_delete_completed
25982         test_mkdir $dir
25983
25984         # check block output
25985         check_lfs_df blocks $dir
25986         # check inode output
25987         check_lfs_df inodes $dir
25988
25989         # create a single file and retest
25990         echo "Creating a single file and testing"
25991         createmany -o $dir/$tfile- 1 &>/dev/null ||
25992                 error "creating 1 file in $dir failed"
25993         check_lfs_df blocks $dir
25994         check_lfs_df inodes $dir
25995
25996         # create a random number of files
25997         echo "Creating $((numfiles - 1)) files and testing"
25998         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25999                 error "creating $((numfiles - 1)) files in $dir failed"
26000
26001         # write a random number of blocks to the first test file
26002         echo "Writing $numblocks 4K blocks and testing"
26003         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26004                 count=$numblocks &>/dev/null ||
26005                 error "dd to $dir/${tfile}-0 failed"
26006
26007         # retest
26008         check_lfs_df blocks $dir
26009         check_lfs_df inodes $dir
26010
26011         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26012                 error "unlinking $numfiles files in $dir failed"
26013 }
26014 run_test 418 "df and lfs df outputs match"
26015
26016 test_419()
26017 {
26018         local dir=$DIR/$tdir
26019
26020         mkdir -p $dir
26021         touch $dir/file
26022
26023         cancel_lru_locks mdc
26024
26025         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26026         $LCTL set_param fail_loc=0x1410
26027         cat $dir/file
26028         $LCTL set_param fail_loc=0
26029         rm -rf $dir
26030 }
26031 run_test 419 "Verify open file by name doesn't crash kernel"
26032
26033 test_420()
26034 {
26035         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26036                 skip "Need MDS version at least 2.12.53"
26037
26038         local SAVE_UMASK=$(umask)
26039         local dir=$DIR/$tdir
26040         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26041
26042         mkdir -p $dir
26043         umask 0000
26044         mkdir -m03777 $dir/testdir
26045         ls -dn $dir/testdir
26046         # Need to remove trailing '.' when SELinux is enabled
26047         local dirperms=$(ls -dn $dir/testdir |
26048                          awk '{ sub(/\.$/, "", $1); print $1}')
26049         [ $dirperms == "drwxrwsrwt" ] ||
26050                 error "incorrect perms on $dir/testdir"
26051
26052         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26053                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26054         ls -n $dir/testdir/testfile
26055         local fileperms=$(ls -n $dir/testdir/testfile |
26056                           awk '{ sub(/\.$/, "", $1); print $1}')
26057         [ $fileperms == "-rwxr-xr-x" ] ||
26058                 error "incorrect perms on $dir/testdir/testfile"
26059
26060         umask $SAVE_UMASK
26061 }
26062 run_test 420 "clear SGID bit on non-directories for non-members"
26063
26064 test_421a() {
26065         local cnt
26066         local fid1
26067         local fid2
26068
26069         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26070                 skip "Need MDS version at least 2.12.54"
26071
26072         test_mkdir $DIR/$tdir
26073         createmany -o $DIR/$tdir/f 3
26074         cnt=$(ls -1 $DIR/$tdir | wc -l)
26075         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26076
26077         fid1=$(lfs path2fid $DIR/$tdir/f1)
26078         fid2=$(lfs path2fid $DIR/$tdir/f2)
26079         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26080
26081         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26082         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26083
26084         cnt=$(ls -1 $DIR/$tdir | wc -l)
26085         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26086
26087         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26088         createmany -o $DIR/$tdir/f 3
26089         cnt=$(ls -1 $DIR/$tdir | wc -l)
26090         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26091
26092         fid1=$(lfs path2fid $DIR/$tdir/f1)
26093         fid2=$(lfs path2fid $DIR/$tdir/f2)
26094         echo "remove using fsname $FSNAME"
26095         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26096
26097         cnt=$(ls -1 $DIR/$tdir | wc -l)
26098         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26099 }
26100 run_test 421a "simple rm by fid"
26101
26102 test_421b() {
26103         local cnt
26104         local FID1
26105         local FID2
26106
26107         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26108                 skip "Need MDS version at least 2.12.54"
26109
26110         test_mkdir $DIR/$tdir
26111         createmany -o $DIR/$tdir/f 3
26112         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26113         MULTIPID=$!
26114
26115         FID1=$(lfs path2fid $DIR/$tdir/f1)
26116         FID2=$(lfs path2fid $DIR/$tdir/f2)
26117         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26118
26119         kill -USR1 $MULTIPID
26120         wait
26121
26122         cnt=$(ls $DIR/$tdir | wc -l)
26123         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26124 }
26125 run_test 421b "rm by fid on open file"
26126
26127 test_421c() {
26128         local cnt
26129         local FIDS
26130
26131         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26132                 skip "Need MDS version at least 2.12.54"
26133
26134         test_mkdir $DIR/$tdir
26135         createmany -o $DIR/$tdir/f 3
26136         touch $DIR/$tdir/$tfile
26137         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26138         cnt=$(ls -1 $DIR/$tdir | wc -l)
26139         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26140
26141         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26142         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26143
26144         cnt=$(ls $DIR/$tdir | wc -l)
26145         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26146 }
26147 run_test 421c "rm by fid against hardlinked files"
26148
26149 test_421d() {
26150         local cnt
26151         local FIDS
26152
26153         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26154                 skip "Need MDS version at least 2.12.54"
26155
26156         test_mkdir $DIR/$tdir
26157         createmany -o $DIR/$tdir/f 4097
26158         cnt=$(ls -1 $DIR/$tdir | wc -l)
26159         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26160
26161         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26162         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26163
26164         cnt=$(ls $DIR/$tdir | wc -l)
26165         rm -rf $DIR/$tdir
26166         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26167 }
26168 run_test 421d "rmfid en masse"
26169
26170 test_421e() {
26171         local cnt
26172         local FID
26173
26174         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26175         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26176                 skip "Need MDS version at least 2.12.54"
26177
26178         mkdir -p $DIR/$tdir
26179         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26180         createmany -o $DIR/$tdir/striped_dir/f 512
26181         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26182         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26183
26184         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26185                 sed "s/[/][^:]*://g")
26186         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26187
26188         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26189         rm -rf $DIR/$tdir
26190         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26191 }
26192 run_test 421e "rmfid in DNE"
26193
26194 test_421f() {
26195         local cnt
26196         local FID
26197
26198         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26199                 skip "Need MDS version at least 2.12.54"
26200
26201         test_mkdir $DIR/$tdir
26202         touch $DIR/$tdir/f
26203         cnt=$(ls -1 $DIR/$tdir | wc -l)
26204         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26205
26206         FID=$(lfs path2fid $DIR/$tdir/f)
26207         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26208         # rmfid should fail
26209         cnt=$(ls -1 $DIR/$tdir | wc -l)
26210         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26211
26212         chmod a+rw $DIR/$tdir
26213         ls -la $DIR/$tdir
26214         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26215         # rmfid should fail
26216         cnt=$(ls -1 $DIR/$tdir | wc -l)
26217         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26218
26219         rm -f $DIR/$tdir/f
26220         $RUNAS touch $DIR/$tdir/f
26221         FID=$(lfs path2fid $DIR/$tdir/f)
26222         echo "rmfid as root"
26223         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26224         cnt=$(ls -1 $DIR/$tdir | wc -l)
26225         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26226
26227         rm -f $DIR/$tdir/f
26228         $RUNAS touch $DIR/$tdir/f
26229         cnt=$(ls -1 $DIR/$tdir | wc -l)
26230         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26231         FID=$(lfs path2fid $DIR/$tdir/f)
26232         # rmfid w/o user_fid2path mount option should fail
26233         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26234         cnt=$(ls -1 $DIR/$tdir | wc -l)
26235         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26236
26237         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26238         stack_trap "rmdir $tmpdir"
26239         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26240                 error "failed to mount client'"
26241         stack_trap "umount_client $tmpdir"
26242
26243         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26244         # rmfid should succeed
26245         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26246         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26247
26248         # rmfid shouldn't allow to remove files due to dir's permission
26249         chmod a+rwx $tmpdir/$tdir
26250         touch $tmpdir/$tdir/f
26251         ls -la $tmpdir/$tdir
26252         FID=$(lfs path2fid $tmpdir/$tdir/f)
26253         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26254         return 0
26255 }
26256 run_test 421f "rmfid checks permissions"
26257
26258 test_421g() {
26259         local cnt
26260         local FIDS
26261
26262         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26263         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26264                 skip "Need MDS version at least 2.12.54"
26265
26266         mkdir -p $DIR/$tdir
26267         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26268         createmany -o $DIR/$tdir/striped_dir/f 512
26269         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26270         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26271
26272         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26273                 sed "s/[/][^:]*://g")
26274
26275         rm -f $DIR/$tdir/striped_dir/f1*
26276         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26277         removed=$((512 - cnt))
26278
26279         # few files have been just removed, so we expect
26280         # rmfid to fail on their fids
26281         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26282         [ $removed != $errors ] && error "$errors != $removed"
26283
26284         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26285         rm -rf $DIR/$tdir
26286         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26287 }
26288 run_test 421g "rmfid to return errors properly"
26289
26290 test_422() {
26291         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26292         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26293         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26294         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26295         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26296
26297         local amc=$(at_max_get client)
26298         local amo=$(at_max_get mds1)
26299         local timeout=`lctl get_param -n timeout`
26300
26301         at_max_set 0 client
26302         at_max_set 0 mds1
26303
26304 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26305         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26306                         fail_val=$(((2*timeout + 10)*1000))
26307         touch $DIR/$tdir/d3/file &
26308         sleep 2
26309 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26310         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26311                         fail_val=$((2*timeout + 5))
26312         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26313         local pid=$!
26314         sleep 1
26315         kill -9 $pid
26316         sleep $((2 * timeout))
26317         echo kill $pid
26318         kill -9 $pid
26319         lctl mark touch
26320         touch $DIR/$tdir/d2/file3
26321         touch $DIR/$tdir/d2/file4
26322         touch $DIR/$tdir/d2/file5
26323
26324         wait
26325         at_max_set $amc client
26326         at_max_set $amo mds1
26327
26328         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26329         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26330                 error "Watchdog is always throttled"
26331 }
26332 run_test 422 "kill a process with RPC in progress"
26333
26334 stat_test() {
26335     df -h $MOUNT &
26336     df -h $MOUNT &
26337     df -h $MOUNT &
26338     df -h $MOUNT &
26339     df -h $MOUNT &
26340     df -h $MOUNT &
26341 }
26342
26343 test_423() {
26344     local _stats
26345     # ensure statfs cache is expired
26346     sleep 2;
26347
26348     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26349     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26350
26351     return 0
26352 }
26353 run_test 423 "statfs should return a right data"
26354
26355 test_424() {
26356 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26357         $LCTL set_param fail_loc=0x80000522
26358         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26359         rm -f $DIR/$tfile
26360 }
26361 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26362
26363 test_425() {
26364         test_mkdir -c -1 $DIR/$tdir
26365         $LFS setstripe -c -1 $DIR/$tdir
26366
26367         lru_resize_disable "" 100
26368         stack_trap "lru_resize_enable" EXIT
26369
26370         sleep 5
26371
26372         for i in $(seq $((MDSCOUNT * 125))); do
26373                 local t=$DIR/$tdir/$tfile_$i
26374
26375                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26376                         error_noexit "Create file $t"
26377         done
26378         stack_trap "rm -rf $DIR/$tdir" EXIT
26379
26380         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26381                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26382                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26383
26384                 [ $lock_count -le $lru_size ] ||
26385                         error "osc lock count $lock_count > lru size $lru_size"
26386         done
26387
26388         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26389                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26390                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26391
26392                 [ $lock_count -le $lru_size ] ||
26393                         error "mdc lock count $lock_count > lru size $lru_size"
26394         done
26395 }
26396 run_test 425 "lock count should not exceed lru size"
26397
26398 test_426() {
26399         splice-test -r $DIR/$tfile
26400         splice-test -rd $DIR/$tfile
26401         splice-test $DIR/$tfile
26402         splice-test -d $DIR/$tfile
26403 }
26404 run_test 426 "splice test on Lustre"
26405
26406 test_427() {
26407         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26408         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26409                 skip "Need MDS version at least 2.12.4"
26410         local log
26411
26412         mkdir $DIR/$tdir
26413         mkdir $DIR/$tdir/1
26414         mkdir $DIR/$tdir/2
26415         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26416         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26417
26418         $LFS getdirstripe $DIR/$tdir/1/dir
26419
26420         #first setfattr for creating updatelog
26421         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26422
26423 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26424         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26425         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26426         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26427
26428         sleep 2
26429         fail mds2
26430         wait_recovery_complete mds2 $((2*TIMEOUT))
26431
26432         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26433         echo $log | grep "get update log failed" &&
26434                 error "update log corruption is detected" || true
26435 }
26436 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26437
26438 test_428() {
26439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26440         local cache_limit=$CACHE_MAX
26441
26442         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26443         $LCTL set_param -n llite.*.max_cached_mb=64
26444
26445         mkdir $DIR/$tdir
26446         $LFS setstripe -c 1 $DIR/$tdir
26447         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26448         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26449         #test write
26450         for f in $(seq 4); do
26451                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26452         done
26453         wait
26454
26455         cancel_lru_locks osc
26456         # Test read
26457         for f in $(seq 4); do
26458                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26459         done
26460         wait
26461 }
26462 run_test 428 "large block size IO should not hang"
26463
26464 test_429() { # LU-7915 / LU-10948
26465         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26466         local testfile=$DIR/$tfile
26467         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26468         local new_flag=1
26469         local first_rpc
26470         local second_rpc
26471         local third_rpc
26472
26473         $LCTL get_param $ll_opencache_threshold_count ||
26474                 skip "client does not have opencache parameter"
26475
26476         set_opencache $new_flag
26477         stack_trap "restore_opencache"
26478         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26479                 error "enable opencache failed"
26480         touch $testfile
26481         # drop MDC DLM locks
26482         cancel_lru_locks mdc
26483         # clear MDC RPC stats counters
26484         $LCTL set_param $mdc_rpcstats=clear
26485
26486         # According to the current implementation, we need to run 3 times
26487         # open & close file to verify if opencache is enabled correctly.
26488         # 1st, RPCs are sent for lookup/open and open handle is released on
26489         #      close finally.
26490         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26491         #      so open handle won't be released thereafter.
26492         # 3rd, No RPC is sent out.
26493         $MULTIOP $testfile oc || error "multiop failed"
26494         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26495         echo "1st: $first_rpc RPCs in flight"
26496
26497         $MULTIOP $testfile oc || error "multiop failed"
26498         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26499         echo "2nd: $second_rpc RPCs in flight"
26500
26501         $MULTIOP $testfile oc || error "multiop failed"
26502         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26503         echo "3rd: $third_rpc RPCs in flight"
26504
26505         #verify no MDC RPC is sent
26506         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26507 }
26508 run_test 429 "verify if opencache flag on client side does work"
26509
26510 lseek_test_430() {
26511         local offset
26512         local file=$1
26513
26514         # data at [200K, 400K)
26515         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26516                 error "256K->512K dd fails"
26517         # data at [2M, 3M)
26518         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26519                 error "2M->3M dd fails"
26520         # data at [4M, 5M)
26521         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26522                 error "4M->5M dd fails"
26523         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26524         # start at first component hole #1
26525         printf "Seeking hole from 1000 ... "
26526         offset=$(lseek_test -l 1000 $file)
26527         echo $offset
26528         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26529         printf "Seeking data from 1000 ... "
26530         offset=$(lseek_test -d 1000 $file)
26531         echo $offset
26532         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26533
26534         # start at first component data block
26535         printf "Seeking hole from 300000 ... "
26536         offset=$(lseek_test -l 300000 $file)
26537         echo $offset
26538         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26539         printf "Seeking data from 300000 ... "
26540         offset=$(lseek_test -d 300000 $file)
26541         echo $offset
26542         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26543
26544         # start at the first component but beyond end of object size
26545         printf "Seeking hole from 1000000 ... "
26546         offset=$(lseek_test -l 1000000 $file)
26547         echo $offset
26548         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26549         printf "Seeking data from 1000000 ... "
26550         offset=$(lseek_test -d 1000000 $file)
26551         echo $offset
26552         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26553
26554         # start at second component stripe 2 (empty file)
26555         printf "Seeking hole from 1500000 ... "
26556         offset=$(lseek_test -l 1500000 $file)
26557         echo $offset
26558         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26559         printf "Seeking data from 1500000 ... "
26560         offset=$(lseek_test -d 1500000 $file)
26561         echo $offset
26562         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26563
26564         # start at second component stripe 1 (all data)
26565         printf "Seeking hole from 3000000 ... "
26566         offset=$(lseek_test -l 3000000 $file)
26567         echo $offset
26568         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26569         printf "Seeking data from 3000000 ... "
26570         offset=$(lseek_test -d 3000000 $file)
26571         echo $offset
26572         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26573
26574         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26575                 error "2nd dd fails"
26576         echo "Add data block at 640K...1280K"
26577
26578         # start at before new data block, in hole
26579         printf "Seeking hole from 600000 ... "
26580         offset=$(lseek_test -l 600000 $file)
26581         echo $offset
26582         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26583         printf "Seeking data from 600000 ... "
26584         offset=$(lseek_test -d 600000 $file)
26585         echo $offset
26586         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26587
26588         # start at the first component new data block
26589         printf "Seeking hole from 1000000 ... "
26590         offset=$(lseek_test -l 1000000 $file)
26591         echo $offset
26592         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26593         printf "Seeking data from 1000000 ... "
26594         offset=$(lseek_test -d 1000000 $file)
26595         echo $offset
26596         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26597
26598         # start at second component stripe 2, new data
26599         printf "Seeking hole from 1200000 ... "
26600         offset=$(lseek_test -l 1200000 $file)
26601         echo $offset
26602         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26603         printf "Seeking data from 1200000 ... "
26604         offset=$(lseek_test -d 1200000 $file)
26605         echo $offset
26606         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26607
26608         # start beyond file end
26609         printf "Using offset > filesize ... "
26610         lseek_test -l 4000000 $file && error "lseek should fail"
26611         printf "Using offset > filesize ... "
26612         lseek_test -d 4000000 $file && error "lseek should fail"
26613
26614         printf "Done\n\n"
26615 }
26616
26617 test_430a() {
26618         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26619                 skip "MDT does not support SEEK_HOLE"
26620
26621         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26622                 skip "OST does not support SEEK_HOLE"
26623
26624         local file=$DIR/$tdir/$tfile
26625
26626         mkdir -p $DIR/$tdir
26627
26628         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26629         # OST stripe #1 will have continuous data at [1M, 3M)
26630         # OST stripe #2 is empty
26631         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26632         lseek_test_430 $file
26633         rm $file
26634         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26635         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26636         lseek_test_430 $file
26637         rm $file
26638         $LFS setstripe -c2 -S 512K $file
26639         echo "Two stripes, stripe size 512K"
26640         lseek_test_430 $file
26641         rm $file
26642         # FLR with stale mirror
26643         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26644                        -N -c2 -S 1M $file
26645         echo "Mirrored file:"
26646         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26647         echo "Plain 2 stripes 1M"
26648         lseek_test_430 $file
26649         rm $file
26650 }
26651 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26652
26653 test_430b() {
26654         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26655                 skip "OST does not support SEEK_HOLE"
26656
26657         local offset
26658         local file=$DIR/$tdir/$tfile
26659
26660         mkdir -p $DIR/$tdir
26661         # Empty layout lseek should fail
26662         $MCREATE $file
26663         # seek from 0
26664         printf "Seeking hole from 0 ... "
26665         lseek_test -l 0 $file && error "lseek should fail"
26666         printf "Seeking data from 0 ... "
26667         lseek_test -d 0 $file && error "lseek should fail"
26668         rm $file
26669
26670         # 1M-hole file
26671         $LFS setstripe -E 1M -c2 -E eof $file
26672         $TRUNCATE $file 1048576
26673         printf "Seeking hole from 1000000 ... "
26674         offset=$(lseek_test -l 1000000 $file)
26675         echo $offset
26676         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26677         printf "Seeking data from 1000000 ... "
26678         lseek_test -d 1000000 $file && error "lseek should fail"
26679         rm $file
26680
26681         # full component followed by non-inited one
26682         $LFS setstripe -E 1M -c2 -E eof $file
26683         dd if=/dev/urandom of=$file bs=1M count=1
26684         printf "Seeking hole from 1000000 ... "
26685         offset=$(lseek_test -l 1000000 $file)
26686         echo $offset
26687         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26688         printf "Seeking hole from 1048576 ... "
26689         lseek_test -l 1048576 $file && error "lseek should fail"
26690         # init second component and truncate back
26691         echo "123" >> $file
26692         $TRUNCATE $file 1048576
26693         printf "Seeking hole from 1000000 ... "
26694         offset=$(lseek_test -l 1000000 $file)
26695         echo $offset
26696         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26697         printf "Seeking hole from 1048576 ... "
26698         lseek_test -l 1048576 $file && error "lseek should fail"
26699         # boundary checks for big values
26700         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26701         offset=$(lseek_test -d 0 $file.10g)
26702         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26703         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26704         offset=$(lseek_test -d 0 $file.100g)
26705         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26706         return 0
26707 }
26708 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26709
26710 test_430c() {
26711         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26712                 skip "OST does not support SEEK_HOLE"
26713
26714         local file=$DIR/$tdir/$tfile
26715         local start
26716
26717         mkdir -p $DIR/$tdir
26718         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26719
26720         # cp version 8.33+ prefers lseek over fiemap
26721         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26722                 start=$SECONDS
26723                 time cp $file /dev/null
26724                 (( SECONDS - start < 5 )) ||
26725                         error "cp: too long runtime $((SECONDS - start))"
26726
26727         fi
26728         # tar version 1.29+ supports SEEK_HOLE/DATA
26729         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26730                 start=$SECONDS
26731                 time tar cS $file - | cat > /dev/null
26732                 (( SECONDS - start < 5 )) ||
26733                         error "tar: too long runtime $((SECONDS - start))"
26734         fi
26735 }
26736 run_test 430c "lseek: external tools check"
26737
26738 test_431() { # LU-14187
26739         local file=$DIR/$tdir/$tfile
26740
26741         mkdir -p $DIR/$tdir
26742         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26743         dd if=/dev/urandom of=$file bs=4k count=1
26744         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26745         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26746         #define OBD_FAIL_OST_RESTART_IO 0x251
26747         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26748         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26749         cp $file $file.0
26750         cancel_lru_locks
26751         sync_all_data
26752         echo 3 > /proc/sys/vm/drop_caches
26753         diff  $file $file.0 || error "data diff"
26754 }
26755 run_test 431 "Restart transaction for IO"
26756
26757 cleanup_test_432() {
26758         do_facet mgs $LCTL nodemap_activate 0
26759         wait_nm_sync active
26760 }
26761
26762 test_432() {
26763         local tmpdir=$TMP/dir432
26764
26765         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26766                 skip "Need MDS version at least 2.14.52"
26767
26768         stack_trap cleanup_test_432 EXIT
26769         mkdir $DIR/$tdir
26770         mkdir $tmpdir
26771
26772         do_facet mgs $LCTL nodemap_activate 1
26773         wait_nm_sync active
26774         do_facet mgs $LCTL nodemap_modify --name default \
26775                 --property admin --value 1
26776         do_facet mgs $LCTL nodemap_modify --name default \
26777                 --property trusted --value 1
26778         cancel_lru_locks mdc
26779         wait_nm_sync default admin_nodemap
26780         wait_nm_sync default trusted_nodemap
26781
26782         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26783                grep -ci "Operation not permitted") -ne 0 ]; then
26784                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26785         fi
26786 }
26787 run_test 432 "mv dir from outside Lustre"
26788
26789 prep_801() {
26790         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26791         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26792                 skip "Need server version at least 2.9.55"
26793
26794         start_full_debug_logging
26795 }
26796
26797 post_801() {
26798         stop_full_debug_logging
26799 }
26800
26801 barrier_stat() {
26802         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26803                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26804                            awk '/The barrier for/ { print $7 }')
26805                 echo $st
26806         else
26807                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26808                 echo \'$st\'
26809         fi
26810 }
26811
26812 barrier_expired() {
26813         local expired
26814
26815         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26816                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26817                           awk '/will be expired/ { print $7 }')
26818         else
26819                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26820         fi
26821
26822         echo $expired
26823 }
26824
26825 test_801a() {
26826         prep_801
26827
26828         echo "Start barrier_freeze at: $(date)"
26829         #define OBD_FAIL_BARRIER_DELAY          0x2202
26830         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26831         # Do not reduce barrier time - See LU-11873
26832         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26833
26834         sleep 2
26835         local b_status=$(barrier_stat)
26836         echo "Got barrier status at: $(date)"
26837         [ "$b_status" = "'freezing_p1'" ] ||
26838                 error "(1) unexpected barrier status $b_status"
26839
26840         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26841         wait
26842         b_status=$(barrier_stat)
26843         [ "$b_status" = "'frozen'" ] ||
26844                 error "(2) unexpected barrier status $b_status"
26845
26846         local expired=$(barrier_expired)
26847         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26848         sleep $((expired + 3))
26849
26850         b_status=$(barrier_stat)
26851         [ "$b_status" = "'expired'" ] ||
26852                 error "(3) unexpected barrier status $b_status"
26853
26854         # Do not reduce barrier time - See LU-11873
26855         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26856                 error "(4) fail to freeze barrier"
26857
26858         b_status=$(barrier_stat)
26859         [ "$b_status" = "'frozen'" ] ||
26860                 error "(5) unexpected barrier status $b_status"
26861
26862         echo "Start barrier_thaw at: $(date)"
26863         #define OBD_FAIL_BARRIER_DELAY          0x2202
26864         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26865         do_facet mgs $LCTL barrier_thaw $FSNAME &
26866
26867         sleep 2
26868         b_status=$(barrier_stat)
26869         echo "Got barrier status at: $(date)"
26870         [ "$b_status" = "'thawing'" ] ||
26871                 error "(6) unexpected barrier status $b_status"
26872
26873         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26874         wait
26875         b_status=$(barrier_stat)
26876         [ "$b_status" = "'thawed'" ] ||
26877                 error "(7) unexpected barrier status $b_status"
26878
26879         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26880         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26881         do_facet mgs $LCTL barrier_freeze $FSNAME
26882
26883         b_status=$(barrier_stat)
26884         [ "$b_status" = "'failed'" ] ||
26885                 error "(8) unexpected barrier status $b_status"
26886
26887         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26888         do_facet mgs $LCTL barrier_thaw $FSNAME
26889
26890         post_801
26891 }
26892 run_test 801a "write barrier user interfaces and stat machine"
26893
26894 test_801b() {
26895         prep_801
26896
26897         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26898         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26899         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26900         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26901         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26902
26903         cancel_lru_locks mdc
26904
26905         # 180 seconds should be long enough
26906         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26907
26908         local b_status=$(barrier_stat)
26909         [ "$b_status" = "'frozen'" ] ||
26910                 error "(6) unexpected barrier status $b_status"
26911
26912         mkdir $DIR/$tdir/d0/d10 &
26913         mkdir_pid=$!
26914
26915         touch $DIR/$tdir/d1/f13 &
26916         touch_pid=$!
26917
26918         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26919         ln_pid=$!
26920
26921         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26922         mv_pid=$!
26923
26924         rm -f $DIR/$tdir/d4/f12 &
26925         rm_pid=$!
26926
26927         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26928
26929         # To guarantee taht the 'stat' is not blocked
26930         b_status=$(barrier_stat)
26931         [ "$b_status" = "'frozen'" ] ||
26932                 error "(8) unexpected barrier status $b_status"
26933
26934         # let above commands to run at background
26935         sleep 5
26936
26937         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26938         ps -p $touch_pid || error "(10) touch should be blocked"
26939         ps -p $ln_pid || error "(11) link should be blocked"
26940         ps -p $mv_pid || error "(12) rename should be blocked"
26941         ps -p $rm_pid || error "(13) unlink should be blocked"
26942
26943         b_status=$(barrier_stat)
26944         [ "$b_status" = "'frozen'" ] ||
26945                 error "(14) unexpected barrier status $b_status"
26946
26947         do_facet mgs $LCTL barrier_thaw $FSNAME
26948         b_status=$(barrier_stat)
26949         [ "$b_status" = "'thawed'" ] ||
26950                 error "(15) unexpected barrier status $b_status"
26951
26952         wait $mkdir_pid || error "(16) mkdir should succeed"
26953         wait $touch_pid || error "(17) touch should succeed"
26954         wait $ln_pid || error "(18) link should succeed"
26955         wait $mv_pid || error "(19) rename should succeed"
26956         wait $rm_pid || error "(20) unlink should succeed"
26957
26958         post_801
26959 }
26960 run_test 801b "modification will be blocked by write barrier"
26961
26962 test_801c() {
26963         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26964
26965         prep_801
26966
26967         stop mds2 || error "(1) Fail to stop mds2"
26968
26969         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26970
26971         local b_status=$(barrier_stat)
26972         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26973                 do_facet mgs $LCTL barrier_thaw $FSNAME
26974                 error "(2) unexpected barrier status $b_status"
26975         }
26976
26977         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26978                 error "(3) Fail to rescan barrier bitmap"
26979
26980         # Do not reduce barrier time - See LU-11873
26981         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26982
26983         b_status=$(barrier_stat)
26984         [ "$b_status" = "'frozen'" ] ||
26985                 error "(4) unexpected barrier status $b_status"
26986
26987         do_facet mgs $LCTL barrier_thaw $FSNAME
26988         b_status=$(barrier_stat)
26989         [ "$b_status" = "'thawed'" ] ||
26990                 error "(5) unexpected barrier status $b_status"
26991
26992         local devname=$(mdsdevname 2)
26993
26994         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26995
26996         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26997                 error "(7) Fail to rescan barrier bitmap"
26998
26999         post_801
27000 }
27001 run_test 801c "rescan barrier bitmap"
27002
27003 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27004 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27005 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27006 saved_MOUNT_OPTS=$MOUNT_OPTS
27007
27008 cleanup_802a() {
27009         trap 0
27010
27011         stopall
27012         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27013         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27014         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27015         MOUNT_OPTS=$saved_MOUNT_OPTS
27016         setupall
27017 }
27018
27019 test_802a() {
27020         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27021         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27022         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27023                 skip "Need server version at least 2.9.55"
27024
27025         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27026
27027         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27028
27029         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27030                 error "(2) Fail to copy"
27031
27032         trap cleanup_802a EXIT
27033
27034         # sync by force before remount as readonly
27035         sync; sync_all_data; sleep 3; sync_all_data
27036
27037         stopall
27038
27039         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27040         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27041         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27042
27043         echo "Mount the server as read only"
27044         setupall server_only || error "(3) Fail to start servers"
27045
27046         echo "Mount client without ro should fail"
27047         mount_client $MOUNT &&
27048                 error "(4) Mount client without 'ro' should fail"
27049
27050         echo "Mount client with ro should succeed"
27051         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27052         mount_client $MOUNT ||
27053                 error "(5) Mount client with 'ro' should succeed"
27054
27055         echo "Modify should be refused"
27056         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27057
27058         echo "Read should be allowed"
27059         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27060                 error "(7) Read should succeed under ro mode"
27061
27062         cleanup_802a
27063 }
27064 run_test 802a "simulate readonly device"
27065
27066 test_802b() {
27067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27068         remote_mds_nodsh && skip "remote MDS with nodsh"
27069
27070         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27071                 skip "readonly option not available"
27072
27073         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27074
27075         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27076                 error "(2) Fail to copy"
27077
27078         # write back all cached data before setting MDT to readonly
27079         cancel_lru_locks
27080         sync_all_data
27081
27082         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27083         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27084
27085         echo "Modify should be refused"
27086         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27087
27088         echo "Read should be allowed"
27089         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27090                 error "(7) Read should succeed under ro mode"
27091
27092         # disable readonly
27093         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27094 }
27095 run_test 802b "be able to set MDTs to readonly"
27096
27097 test_803a() {
27098         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27099         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27100                 skip "MDS needs to be newer than 2.10.54"
27101
27102         mkdir_on_mdt0 $DIR/$tdir
27103         # Create some objects on all MDTs to trigger related logs objects
27104         for idx in $(seq $MDSCOUNT); do
27105                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27106                         $DIR/$tdir/dir${idx} ||
27107                         error "Fail to create $DIR/$tdir/dir${idx}"
27108         done
27109
27110         sync; sleep 3
27111         wait_delete_completed # ensure old test cleanups are finished
27112         echo "before create:"
27113         $LFS df -i $MOUNT
27114         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27115
27116         for i in {1..10}; do
27117                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27118                         error "Fail to create $DIR/$tdir/foo$i"
27119         done
27120
27121         sync; sleep 3
27122         echo "after create:"
27123         $LFS df -i $MOUNT
27124         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27125
27126         # allow for an llog to be cleaned up during the test
27127         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27128                 error "before ($before_used) + 10 > after ($after_used)"
27129
27130         for i in {1..10}; do
27131                 rm -rf $DIR/$tdir/foo$i ||
27132                         error "Fail to remove $DIR/$tdir/foo$i"
27133         done
27134
27135         sleep 3 # avoid MDT return cached statfs
27136         wait_delete_completed
27137         echo "after unlink:"
27138         $LFS df -i $MOUNT
27139         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27140
27141         # allow for an llog to be created during the test
27142         [ $after_used -le $((before_used + 1)) ] ||
27143                 error "after ($after_used) > before ($before_used) + 1"
27144 }
27145 run_test 803a "verify agent object for remote object"
27146
27147 test_803b() {
27148         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27149         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27150                 skip "MDS needs to be newer than 2.13.56"
27151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27152
27153         for i in $(seq 0 $((MDSCOUNT - 1))); do
27154                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27155         done
27156
27157         local before=0
27158         local after=0
27159
27160         local tmp
27161
27162         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27163         for i in $(seq 0 $((MDSCOUNT - 1))); do
27164                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27165                         awk '/getattr/ { print $2 }')
27166                 before=$((before + tmp))
27167         done
27168         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27169         for i in $(seq 0 $((MDSCOUNT - 1))); do
27170                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27171                         awk '/getattr/ { print $2 }')
27172                 after=$((after + tmp))
27173         done
27174
27175         [ $before -eq $after ] || error "getattr count $before != $after"
27176 }
27177 run_test 803b "remote object can getattr from cache"
27178
27179 test_804() {
27180         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27181         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27182                 skip "MDS needs to be newer than 2.10.54"
27183         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27184
27185         mkdir -p $DIR/$tdir
27186         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27187                 error "Fail to create $DIR/$tdir/dir0"
27188
27189         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27190         local dev=$(mdsdevname 2)
27191
27192         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27193                 grep ${fid} || error "NOT found agent entry for dir0"
27194
27195         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27196                 error "Fail to create $DIR/$tdir/dir1"
27197
27198         touch $DIR/$tdir/dir1/foo0 ||
27199                 error "Fail to create $DIR/$tdir/dir1/foo0"
27200         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27201         local rc=0
27202
27203         for idx in $(seq $MDSCOUNT); do
27204                 dev=$(mdsdevname $idx)
27205                 do_facet mds${idx} \
27206                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27207                         grep ${fid} && rc=$idx
27208         done
27209
27210         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27211                 error "Fail to rename foo0 to foo1"
27212         if [ $rc -eq 0 ]; then
27213                 for idx in $(seq $MDSCOUNT); do
27214                         dev=$(mdsdevname $idx)
27215                         do_facet mds${idx} \
27216                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27217                         grep ${fid} && rc=$idx
27218                 done
27219         fi
27220
27221         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27222                 error "Fail to rename foo1 to foo2"
27223         if [ $rc -eq 0 ]; then
27224                 for idx in $(seq $MDSCOUNT); do
27225                         dev=$(mdsdevname $idx)
27226                         do_facet mds${idx} \
27227                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27228                         grep ${fid} && rc=$idx
27229                 done
27230         fi
27231
27232         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27233
27234         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27235                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27236         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27237                 error "Fail to rename foo2 to foo0"
27238         unlink $DIR/$tdir/dir1/foo0 ||
27239                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27240         rm -rf $DIR/$tdir/dir0 ||
27241                 error "Fail to rm $DIR/$tdir/dir0"
27242
27243         for idx in $(seq $MDSCOUNT); do
27244                 rc=0
27245
27246                 stop mds${idx}
27247                 dev=$(mdsdevname $idx)
27248                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27249                         rc=$?
27250                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27251                         error "mount mds$idx failed"
27252                 df $MOUNT > /dev/null 2>&1
27253
27254                 # e2fsck should not return error
27255                 [ $rc -eq 0 ] ||
27256                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27257         done
27258 }
27259 run_test 804 "verify agent entry for remote entry"
27260
27261 cleanup_805() {
27262         do_facet $SINGLEMDS zfs set quota=$old $fsset
27263         unlinkmany $DIR/$tdir/f- 1000000
27264         trap 0
27265 }
27266
27267 test_805() {
27268         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27269         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27270         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27271                 skip "netfree not implemented before 0.7"
27272         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27273                 skip "Need MDS version at least 2.10.57"
27274
27275         local fsset
27276         local freekb
27277         local usedkb
27278         local old
27279         local quota
27280         local pref="osd-zfs.$FSNAME-MDT0000."
27281
27282         # limit available space on MDS dataset to meet nospace issue
27283         # quickly. then ZFS 0.7.2 can use reserved space if asked
27284         # properly (using netfree flag in osd_declare_destroy()
27285         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27286         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27287                 gawk '{print $3}')
27288         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27289         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27290         let "usedkb=usedkb-freekb"
27291         let "freekb=freekb/2"
27292         if let "freekb > 5000"; then
27293                 let "freekb=5000"
27294         fi
27295         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27296         trap cleanup_805 EXIT
27297         mkdir_on_mdt0 $DIR/$tdir
27298         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27299                 error "Can't set PFL layout"
27300         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27301         rm -rf $DIR/$tdir || error "not able to remove"
27302         do_facet $SINGLEMDS zfs set quota=$old $fsset
27303         trap 0
27304 }
27305 run_test 805 "ZFS can remove from full fs"
27306
27307 # Size-on-MDS test
27308 check_lsom_data()
27309 {
27310         local file=$1
27311         local expect=$(stat -c %s $file)
27312
27313         check_lsom_size $1 $expect
27314
27315         local blocks=$($LFS getsom -b $file)
27316         expect=$(stat -c %b $file)
27317         [[ $blocks == $expect ]] ||
27318                 error "$file expected blocks: $expect, got: $blocks"
27319 }
27320
27321 check_lsom_size()
27322 {
27323         local size
27324         local expect=$2
27325
27326         cancel_lru_locks mdc
27327
27328         size=$($LFS getsom -s $1)
27329         [[ $size == $expect ]] ||
27330                 error "$file expected size: $expect, got: $size"
27331 }
27332
27333 test_806() {
27334         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27335                 skip "Need MDS version at least 2.11.52"
27336
27337         local bs=1048576
27338
27339         touch $DIR/$tfile || error "touch $tfile failed"
27340
27341         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27342         save_lustre_params client "llite.*.xattr_cache" > $save
27343         lctl set_param llite.*.xattr_cache=0
27344         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27345
27346         # single-threaded write
27347         echo "Test SOM for single-threaded write"
27348         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27349                 error "write $tfile failed"
27350         check_lsom_size $DIR/$tfile $bs
27351
27352         local num=32
27353         local size=$(($num * $bs))
27354         local offset=0
27355         local i
27356
27357         echo "Test SOM for single client multi-threaded($num) write"
27358         $TRUNCATE $DIR/$tfile 0
27359         for ((i = 0; i < $num; i++)); do
27360                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27361                 local pids[$i]=$!
27362                 offset=$((offset + $bs))
27363         done
27364         for (( i=0; i < $num; i++ )); do
27365                 wait ${pids[$i]}
27366         done
27367         check_lsom_size $DIR/$tfile $size
27368
27369         $TRUNCATE $DIR/$tfile 0
27370         for ((i = 0; i < $num; i++)); do
27371                 offset=$((offset - $bs))
27372                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27373                 local pids[$i]=$!
27374         done
27375         for (( i=0; i < $num; i++ )); do
27376                 wait ${pids[$i]}
27377         done
27378         check_lsom_size $DIR/$tfile $size
27379
27380         # multi-client writes
27381         num=$(get_node_count ${CLIENTS//,/ })
27382         size=$(($num * $bs))
27383         offset=0
27384         i=0
27385
27386         echo "Test SOM for multi-client ($num) writes"
27387         $TRUNCATE $DIR/$tfile 0
27388         for client in ${CLIENTS//,/ }; do
27389                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27390                 local pids[$i]=$!
27391                 i=$((i + 1))
27392                 offset=$((offset + $bs))
27393         done
27394         for (( i=0; i < $num; i++ )); do
27395                 wait ${pids[$i]}
27396         done
27397         check_lsom_size $DIR/$tfile $offset
27398
27399         i=0
27400         $TRUNCATE $DIR/$tfile 0
27401         for client in ${CLIENTS//,/ }; do
27402                 offset=$((offset - $bs))
27403                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27404                 local pids[$i]=$!
27405                 i=$((i + 1))
27406         done
27407         for (( i=0; i < $num; i++ )); do
27408                 wait ${pids[$i]}
27409         done
27410         check_lsom_size $DIR/$tfile $size
27411
27412         # verify truncate
27413         echo "Test SOM for truncate"
27414         $TRUNCATE $DIR/$tfile 1048576
27415         check_lsom_size $DIR/$tfile 1048576
27416         $TRUNCATE $DIR/$tfile 1234
27417         check_lsom_size $DIR/$tfile 1234
27418
27419         # verify SOM blocks count
27420         echo "Verify SOM block count"
27421         $TRUNCATE $DIR/$tfile 0
27422         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27423                 error "failed to write file $tfile"
27424         check_lsom_data $DIR/$tfile
27425 }
27426 run_test 806 "Verify Lazy Size on MDS"
27427
27428 test_807() {
27429         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27430         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27431                 skip "Need MDS version at least 2.11.52"
27432
27433         # Registration step
27434         changelog_register || error "changelog_register failed"
27435         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27436         changelog_users $SINGLEMDS | grep -q $cl_user ||
27437                 error "User $cl_user not found in changelog_users"
27438
27439         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27440         save_lustre_params client "llite.*.xattr_cache" > $save
27441         lctl set_param llite.*.xattr_cache=0
27442         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27443
27444         rm -rf $DIR/$tdir || error "rm $tdir failed"
27445         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27446         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27447         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27448         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27449                 error "truncate $tdir/trunc failed"
27450
27451         local bs=1048576
27452         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27453                 error "write $tfile failed"
27454
27455         # multi-client wirtes
27456         local num=$(get_node_count ${CLIENTS//,/ })
27457         local offset=0
27458         local i=0
27459
27460         echo "Test SOM for multi-client ($num) writes"
27461         touch $DIR/$tfile || error "touch $tfile failed"
27462         $TRUNCATE $DIR/$tfile 0
27463         for client in ${CLIENTS//,/ }; do
27464                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27465                 local pids[$i]=$!
27466                 i=$((i + 1))
27467                 offset=$((offset + $bs))
27468         done
27469         for (( i=0; i < $num; i++ )); do
27470                 wait ${pids[$i]}
27471         done
27472
27473         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27474         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27475         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27476         check_lsom_data $DIR/$tdir/trunc
27477         check_lsom_data $DIR/$tdir/single_dd
27478         check_lsom_data $DIR/$tfile
27479
27480         rm -rf $DIR/$tdir
27481         # Deregistration step
27482         changelog_deregister || error "changelog_deregister failed"
27483 }
27484 run_test 807 "verify LSOM syncing tool"
27485
27486 check_som_nologged()
27487 {
27488         local lines=$($LFS changelog $FSNAME-MDT0000 |
27489                 grep 'x=trusted.som' | wc -l)
27490         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27491 }
27492
27493 test_808() {
27494         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27495                 skip "Need MDS version at least 2.11.55"
27496
27497         # Registration step
27498         changelog_register || error "changelog_register failed"
27499
27500         touch $DIR/$tfile || error "touch $tfile failed"
27501         check_som_nologged
27502
27503         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27504                 error "write $tfile failed"
27505         check_som_nologged
27506
27507         $TRUNCATE $DIR/$tfile 1234
27508         check_som_nologged
27509
27510         $TRUNCATE $DIR/$tfile 1048576
27511         check_som_nologged
27512
27513         # Deregistration step
27514         changelog_deregister || error "changelog_deregister failed"
27515 }
27516 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27517
27518 check_som_nodata()
27519 {
27520         $LFS getsom $1
27521         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27522 }
27523
27524 test_809() {
27525         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27526                 skip "Need MDS version at least 2.11.56"
27527
27528         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27529                 error "failed to create DoM-only file $DIR/$tfile"
27530         touch $DIR/$tfile || error "touch $tfile failed"
27531         check_som_nodata $DIR/$tfile
27532
27533         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27534                 error "write $tfile failed"
27535         check_som_nodata $DIR/$tfile
27536
27537         $TRUNCATE $DIR/$tfile 1234
27538         check_som_nodata $DIR/$tfile
27539
27540         $TRUNCATE $DIR/$tfile 4097
27541         check_som_nodata $DIR/$file
27542 }
27543 run_test 809 "Verify no SOM xattr store for DoM-only files"
27544
27545 test_810() {
27546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27547         $GSS && skip_env "could not run with gss"
27548         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27549                 skip "OST < 2.12.58 doesn't align checksum"
27550
27551         set_checksums 1
27552         stack_trap "set_checksums $ORIG_CSUM" EXIT
27553         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27554
27555         local csum
27556         local before
27557         local after
27558         for csum in $CKSUM_TYPES; do
27559                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27560                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27561                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27562                         eval set -- $i
27563                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27564                         before=$(md5sum $DIR/$tfile)
27565                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27566                         after=$(md5sum $DIR/$tfile)
27567                         [ "$before" == "$after" ] ||
27568                                 error "$csum: $before != $after bs=$1 seek=$2"
27569                 done
27570         done
27571 }
27572 run_test 810 "partial page writes on ZFS (LU-11663)"
27573
27574 test_812a() {
27575         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27576                 skip "OST < 2.12.51 doesn't support this fail_loc"
27577
27578         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27579         # ensure ost1 is connected
27580         stat $DIR/$tfile >/dev/null || error "can't stat"
27581         wait_osc_import_state client ost1 FULL
27582         # no locks, no reqs to let the connection idle
27583         cancel_lru_locks osc
27584
27585         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27586 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27587         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27588         wait_osc_import_state client ost1 CONNECTING
27589         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27590
27591         stat $DIR/$tfile >/dev/null || error "can't stat file"
27592 }
27593 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27594
27595 test_812b() { # LU-12378
27596         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27597                 skip "OST < 2.12.51 doesn't support this fail_loc"
27598
27599         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27600         # ensure ost1 is connected
27601         stat $DIR/$tfile >/dev/null || error "can't stat"
27602         wait_osc_import_state client ost1 FULL
27603         # no locks, no reqs to let the connection idle
27604         cancel_lru_locks osc
27605
27606         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27607 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27608         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27609         wait_osc_import_state client ost1 CONNECTING
27610         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27611
27612         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27613         wait_osc_import_state client ost1 IDLE
27614 }
27615 run_test 812b "do not drop no resend request for idle connect"
27616
27617 test_812c() {
27618         local old
27619
27620         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27621
27622         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27623         $LFS getstripe $DIR/$tfile
27624         $LCTL set_param osc.*.idle_timeout=10
27625         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27626         # ensure ost1 is connected
27627         stat $DIR/$tfile >/dev/null || error "can't stat"
27628         wait_osc_import_state client ost1 FULL
27629         # no locks, no reqs to let the connection idle
27630         cancel_lru_locks osc
27631
27632 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27633         $LCTL set_param fail_loc=0x80000533
27634         sleep 15
27635         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27636 }
27637 run_test 812c "idle import vs lock enqueue race"
27638
27639 test_813() {
27640         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27641         [ -z "$file_heat_sav" ] && skip "no file heat support"
27642
27643         local readsample
27644         local writesample
27645         local readbyte
27646         local writebyte
27647         local readsample1
27648         local writesample1
27649         local readbyte1
27650         local writebyte1
27651
27652         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27653         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27654
27655         $LCTL set_param -n llite.*.file_heat=1
27656         echo "Turn on file heat"
27657         echo "Period second: $period_second, Decay percentage: $decay_pct"
27658
27659         echo "QQQQ" > $DIR/$tfile
27660         echo "QQQQ" > $DIR/$tfile
27661         echo "QQQQ" > $DIR/$tfile
27662         cat $DIR/$tfile > /dev/null
27663         cat $DIR/$tfile > /dev/null
27664         cat $DIR/$tfile > /dev/null
27665         cat $DIR/$tfile > /dev/null
27666
27667         local out=$($LFS heat_get $DIR/$tfile)
27668
27669         $LFS heat_get $DIR/$tfile
27670         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27671         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27672         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27673         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27674
27675         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27676         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27677         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27678         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27679
27680         sleep $((period_second + 3))
27681         echo "Sleep $((period_second + 3)) seconds..."
27682         # The recursion formula to calculate the heat of the file f is as
27683         # follow:
27684         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27685         # Where Hi is the heat value in the period between time points i*I and
27686         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27687         # to the weight of Ci.
27688         out=$($LFS heat_get $DIR/$tfile)
27689         $LFS heat_get $DIR/$tfile
27690         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27691         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27692         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27693         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27694
27695         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27696                 error "read sample ($readsample) is wrong"
27697         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27698                 error "write sample ($writesample) is wrong"
27699         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27700                 error "read bytes ($readbyte) is wrong"
27701         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27702                 error "write bytes ($writebyte) is wrong"
27703
27704         echo "QQQQ" > $DIR/$tfile
27705         echo "QQQQ" > $DIR/$tfile
27706         echo "QQQQ" > $DIR/$tfile
27707         cat $DIR/$tfile > /dev/null
27708         cat $DIR/$tfile > /dev/null
27709         cat $DIR/$tfile > /dev/null
27710         cat $DIR/$tfile > /dev/null
27711
27712         sleep $((period_second + 3))
27713         echo "Sleep $((period_second + 3)) seconds..."
27714
27715         out=$($LFS heat_get $DIR/$tfile)
27716         $LFS heat_get $DIR/$tfile
27717         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27718         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27719         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27720         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27721
27722         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27723                 4 * $decay_pct) / 100") -eq 1 ] ||
27724                 error "read sample ($readsample1) is wrong"
27725         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27726                 3 * $decay_pct) / 100") -eq 1 ] ||
27727                 error "write sample ($writesample1) is wrong"
27728         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27729                 20 * $decay_pct) / 100") -eq 1 ] ||
27730                 error "read bytes ($readbyte1) is wrong"
27731         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27732                 15 * $decay_pct) / 100") -eq 1 ] ||
27733                 error "write bytes ($writebyte1) is wrong"
27734
27735         echo "Turn off file heat for the file $DIR/$tfile"
27736         $LFS heat_set -o $DIR/$tfile
27737
27738         echo "QQQQ" > $DIR/$tfile
27739         echo "QQQQ" > $DIR/$tfile
27740         echo "QQQQ" > $DIR/$tfile
27741         cat $DIR/$tfile > /dev/null
27742         cat $DIR/$tfile > /dev/null
27743         cat $DIR/$tfile > /dev/null
27744         cat $DIR/$tfile > /dev/null
27745
27746         out=$($LFS heat_get $DIR/$tfile)
27747         $LFS heat_get $DIR/$tfile
27748         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27749         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27750         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27751         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27752
27753         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27754         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27755         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27756         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27757
27758         echo "Trun on file heat for the file $DIR/$tfile"
27759         $LFS heat_set -O $DIR/$tfile
27760
27761         echo "QQQQ" > $DIR/$tfile
27762         echo "QQQQ" > $DIR/$tfile
27763         echo "QQQQ" > $DIR/$tfile
27764         cat $DIR/$tfile > /dev/null
27765         cat $DIR/$tfile > /dev/null
27766         cat $DIR/$tfile > /dev/null
27767         cat $DIR/$tfile > /dev/null
27768
27769         out=$($LFS heat_get $DIR/$tfile)
27770         $LFS heat_get $DIR/$tfile
27771         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27772         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27773         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27774         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27775
27776         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27777         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27778         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27779         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27780
27781         $LFS heat_set -c $DIR/$tfile
27782         $LCTL set_param -n llite.*.file_heat=0
27783         echo "Turn off file heat support for the Lustre filesystem"
27784
27785         echo "QQQQ" > $DIR/$tfile
27786         echo "QQQQ" > $DIR/$tfile
27787         echo "QQQQ" > $DIR/$tfile
27788         cat $DIR/$tfile > /dev/null
27789         cat $DIR/$tfile > /dev/null
27790         cat $DIR/$tfile > /dev/null
27791         cat $DIR/$tfile > /dev/null
27792
27793         out=$($LFS heat_get $DIR/$tfile)
27794         $LFS heat_get $DIR/$tfile
27795         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27796         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27797         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27798         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27799
27800         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27801         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27802         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27803         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27804
27805         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27806         rm -f $DIR/$tfile
27807 }
27808 run_test 813 "File heat verfication"
27809
27810 test_814()
27811 {
27812         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27813         echo -n y >> $DIR/$tfile
27814         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27815         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27816 }
27817 run_test 814 "sparse cp works as expected (LU-12361)"
27818
27819 test_815()
27820 {
27821         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27822         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27823 }
27824 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27825
27826 test_816() {
27827         local ost1_imp=$(get_osc_import_name client ost1)
27828         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27829                          cut -d'.' -f2)
27830
27831         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27832         # ensure ost1 is connected
27833
27834         stat $DIR/$tfile >/dev/null || error "can't stat"
27835         wait_osc_import_state client ost1 FULL
27836         # no locks, no reqs to let the connection idle
27837         cancel_lru_locks osc
27838         lru_resize_disable osc
27839         local before
27840         local now
27841         before=$($LCTL get_param -n \
27842                  ldlm.namespaces.$imp_name.lru_size)
27843
27844         wait_osc_import_state client ost1 IDLE
27845         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27846         now=$($LCTL get_param -n \
27847               ldlm.namespaces.$imp_name.lru_size)
27848         [ $before == $now ] || error "lru_size changed $before != $now"
27849 }
27850 run_test 816 "do not reset lru_resize on idle reconnect"
27851
27852 cleanup_817() {
27853         umount $tmpdir
27854         exportfs -u localhost:$DIR/nfsexp
27855         rm -rf $DIR/nfsexp
27856 }
27857
27858 test_817() {
27859         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27860
27861         mkdir -p $DIR/nfsexp
27862         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27863                 error "failed to export nfs"
27864
27865         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27866         stack_trap cleanup_817 EXIT
27867
27868         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27869                 error "failed to mount nfs to $tmpdir"
27870
27871         cp /bin/true $tmpdir
27872         $DIR/nfsexp/true || error "failed to execute 'true' command"
27873 }
27874 run_test 817 "nfsd won't cache write lock for exec file"
27875
27876 test_818() {
27877         test_mkdir -i0 -c1 $DIR/$tdir
27878         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27879         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27880         stop $SINGLEMDS
27881
27882         # restore osp-syn threads
27883         stack_trap "fail $SINGLEMDS"
27884
27885         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27886         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27887         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27888                 error "start $SINGLEMDS failed"
27889         rm -rf $DIR/$tdir
27890
27891         local testid=$(echo $TESTNAME | tr '_' ' ')
27892
27893         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27894                 grep "run LFSCK" || error "run LFSCK is not suggested"
27895 }
27896 run_test 818 "unlink with failed llog"
27897
27898 test_819a() {
27899         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27900         cancel_lru_locks osc
27901         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27902         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27903         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27904         rm -f $TDIR/$tfile
27905 }
27906 run_test 819a "too big niobuf in read"
27907
27908 test_819b() {
27909         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27910         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27911         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27912         cancel_lru_locks osc
27913         sleep 1
27914         rm -f $TDIR/$tfile
27915 }
27916 run_test 819b "too big niobuf in write"
27917
27918
27919 function test_820_start_ost() {
27920         sleep 5
27921
27922         for num in $(seq $OSTCOUNT); do
27923                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27924         done
27925 }
27926
27927 test_820() {
27928         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27929
27930         mkdir $DIR/$tdir
27931         umount_client $MOUNT || error "umount failed"
27932         for num in $(seq $OSTCOUNT); do
27933                 stop ost$num
27934         done
27935
27936         # mount client with no active OSTs
27937         # so that the client can't initialize max LOV EA size
27938         # from OSC notifications
27939         mount_client $MOUNT || error "mount failed"
27940         # delay OST starting to keep this 0 max EA size for a while
27941         test_820_start_ost &
27942
27943         # create a directory on MDS2
27944         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27945                 error "Failed to create directory"
27946         # open intent should update default EA size
27947         # see mdc_update_max_ea_from_body()
27948         # notice this is the very first RPC to MDS2
27949         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27950         ret=$?
27951         echo $out
27952         # With SSK, this situation can lead to -EPERM being returned.
27953         # In that case, simply retry.
27954         if [ $ret -ne 0 ] && $SHARED_KEY; then
27955                 if echo "$out" | grep -q "not permitted"; then
27956                         cp /etc/services $DIR/$tdir/mds2
27957                         ret=$?
27958                 fi
27959         fi
27960         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27961 }
27962 run_test 820 "update max EA from open intent"
27963
27964 test_822() {
27965         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27966
27967         save_lustre_params mds1 \
27968                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27969         do_facet $SINGLEMDS "$LCTL set_param -n \
27970                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27971         do_facet $SINGLEMDS "$LCTL set_param -n \
27972                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27973
27974         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27975         local maxage=$(do_facet mds1 $LCTL get_param -n \
27976                        osp.$FSNAME-OST0000*MDT0000.maxage)
27977         sleep $((maxage + 1))
27978
27979         #define OBD_FAIL_NET_ERROR_RPC          0x532
27980         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27981
27982         stack_trap "restore_lustre_params < $p; rm $p"
27983
27984         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27985                       osp.$FSNAME-OST0000*MDT0000.create_count")
27986         for i in $(seq 1 $count); do
27987                 touch $DIR/$tfile.${i} || error "touch failed"
27988         done
27989 }
27990 run_test 822 "test precreate failure"
27991
27992 test_823() {
27993         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27994         local OST_MAX_PRECREATE=20000
27995
27996         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
27997                 skip "Need MDS version at least 2.14.56"
27998
27999         save_lustre_params mds1 \
28000                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28001         do_facet $SINGLEMDS "$LCTL set_param -n \
28002                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28003         do_facet $SINGLEMDS "$LCTL set_param -n \
28004                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28005
28006         stack_trap "restore_lustre_params < $p; rm $p"
28007
28008         do_facet $SINGLEMDS "$LCTL set_param -n \
28009                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28010
28011         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28012                       osp.$FSNAME-OST0000*MDT0000.create_count")
28013         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28014                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28015         local expect_count=$(((($max/2)/256) * 256))
28016
28017         log "setting create_count to 100200:"
28018         log " -result- count: $count with max: $max, expecting: $expect_count"
28019
28020         [[ $count -eq expect_count ]] ||
28021                 error "Create count not set to max precreate."
28022 }
28023 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28024
28025 test_831() {
28026         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28027                 skip "Need MDS version 2.14.56"
28028
28029         local sync_changes=$(do_facet $SINGLEMDS \
28030                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28031
28032         [ "$sync_changes" -gt 100 ] &&
28033                 skip "Sync changes $sync_changes > 100 already"
28034
28035         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28036
28037         $LFS mkdir -i 0 $DIR/$tdir
28038         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28039
28040         save_lustre_params mds1 \
28041                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28042         save_lustre_params mds1 \
28043                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28044
28045         do_facet mds1 "$LCTL set_param -n \
28046                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28047                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28048         stack_trap "restore_lustre_params < $p" EXIT
28049
28050         createmany -o $DIR/$tdir/f- 1000
28051         unlinkmany $DIR/$tdir/f- 1000 &
28052         local UNLINK_PID=$!
28053
28054         while sleep 1; do
28055                 sync_changes=$(do_facet mds1 \
28056                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28057                 # the check in the code is racy, fail the test
28058                 # if the value above the limit by 10.
28059                 [ $sync_changes -gt 110 ] && {
28060                         kill -2 $UNLINK_PID
28061                         wait
28062                         error "osp changes throttling failed, $sync_changes>110"
28063                 }
28064                 kill -0 $UNLINK_PID 2> /dev/null || break
28065         done
28066         wait
28067 }
28068 run_test 831 "throttling unlink/setattr queuing on OSP"
28069
28070 #
28071 # tests that do cleanup/setup should be run at the end
28072 #
28073
28074 test_900() {
28075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28076         local ls
28077
28078         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28079         $LCTL set_param fail_loc=0x903
28080
28081         cancel_lru_locks MGC
28082
28083         FAIL_ON_ERROR=true cleanup
28084         FAIL_ON_ERROR=true setup
28085 }
28086 run_test 900 "umount should not race with any mgc requeue thread"
28087
28088 # LUS-6253/LU-11185
28089 test_901() {
28090         local old
28091         local count
28092         local oldc
28093         local newc
28094         local olds
28095         local news
28096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28097
28098         # some get_param have a bug to handle dot in param name
28099         cancel_lru_locks MGC
28100         old=$(mount -t lustre | wc -l)
28101         # 1 config+sptlrpc
28102         # 2 params
28103         # 3 nodemap
28104         # 4 IR
28105         old=$((old * 4))
28106         oldc=0
28107         count=0
28108         while [ $old -ne $oldc ]; do
28109                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28110                 sleep 1
28111                 ((count++))
28112                 if [ $count -ge $TIMEOUT ]; then
28113                         error "too large timeout"
28114                 fi
28115         done
28116         umount_client $MOUNT || error "umount failed"
28117         mount_client $MOUNT || error "mount failed"
28118         cancel_lru_locks MGC
28119         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28120
28121         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28122
28123         return 0
28124 }
28125 run_test 901 "don't leak a mgc lock on client umount"
28126
28127 # LU-13377
28128 test_902() {
28129         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28130                 skip "client does not have LU-13377 fix"
28131         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28132         $LCTL set_param fail_loc=0x1415
28133         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28134         cancel_lru_locks osc
28135         rm -f $DIR/$tfile
28136 }
28137 run_test 902 "test short write doesn't hang lustre"
28138
28139 # LU-14711
28140 test_903() {
28141         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28142         echo "blah" > $DIR/${tfile}-2
28143         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28144         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28145         $LCTL set_param fail_loc=0x417 fail_val=20
28146
28147         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28148         sleep 1 # To start the destroy
28149         wait_destroy_complete 150 || error "Destroy taking too long"
28150         cat $DIR/$tfile > /dev/null || error "Evicted"
28151 }
28152 run_test 903 "Test long page discard does not cause evictions"
28153
28154 test_904() {
28155         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28156         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28157                 grep -q project || skip "skip project quota not supported"
28158
28159         local testfile="$DIR/$tdir/$tfile"
28160         local xattr="trusted.projid"
28161         local projid
28162         local mdts=$(comma_list $(mdts_nodes))
28163         local saved=$(do_facet mds1 $LCTL get_param -n \
28164                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28165
28166         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28167         stack_trap "do_nodes $mdts $LCTL set_param \
28168                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28169
28170         mkdir -p $DIR/$tdir
28171         touch $testfile
28172         #hide projid xattr on server
28173         $LFS project -p 1 $testfile ||
28174                 error "set $testfile project id failed"
28175         getfattr -m - $testfile | grep $xattr &&
28176                 error "do not show trusted.projid when disabled on server"
28177         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28178         #should be hidden when projid is 0
28179         $LFS project -p 0 $testfile ||
28180                 error "set $testfile project id failed"
28181         getfattr -m - $testfile | grep $xattr &&
28182                 error "do not show trusted.projid with project ID 0"
28183
28184         #still can getxattr explicitly
28185         projid=$(getfattr -n $xattr $testfile |
28186                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28187         [ $projid == "0" ] ||
28188                 error "projid expected 0 not $projid"
28189
28190         #set the projid via setxattr
28191         setfattr -n $xattr -v "1000" $testfile ||
28192                 error "setattr failed with $?"
28193         projid=($($LFS project $testfile))
28194         [ ${projid[0]} == "1000" ] ||
28195                 error "projid expected 1000 not $projid"
28196
28197         #check the new projid via getxattr
28198         $LFS project -p 1001 $testfile ||
28199                 error "set $testfile project id failed"
28200         getfattr -m - $testfile | grep $xattr ||
28201                 error "should show trusted.projid when project ID != 0"
28202         projid=$(getfattr -n $xattr $testfile |
28203                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28204         [ $projid == "1001" ] ||
28205                 error "projid expected 1001 not $projid"
28206
28207         #try to set invalid projid
28208         setfattr -n $xattr -v "4294967295" $testfile &&
28209                 error "set invalid projid should fail"
28210
28211         #remove the xattr means setting projid to 0
28212         setfattr -x $xattr $testfile ||
28213                 error "setfattr failed with $?"
28214         projid=($($LFS project $testfile))
28215         [ ${projid[0]} == "0" ] ||
28216                 error "projid expected 0 not $projid"
28217
28218         #should be hidden when parent has inherit flag and same projid
28219         $LFS project -srp 1002 $DIR/$tdir ||
28220                 error "set $tdir project id failed"
28221         getfattr -m - $testfile | grep $xattr &&
28222                 error "do not show trusted.projid with inherit flag"
28223
28224         #still can getxattr explicitly
28225         projid=$(getfattr -n $xattr $testfile |
28226                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28227         [ $projid == "1002" ] ||
28228                 error "projid expected 1002 not $projid"
28229 }
28230 run_test 904 "virtual project ID xattr"
28231
28232 complete $SECONDS
28233 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28234 check_and_cleanup_lustre
28235 if [ "$I_MOUNTED" != "yes" ]; then
28236         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28237 fi
28238 exit_status