Whamcloud - gitweb
LU-6864 osp: manage number of modify RPCs in flight
[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 test_116a() { # was previously test_116()
11950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11951         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11952         remote_mds_nodsh && skip "remote MDS with nodsh"
11953
11954         echo -n "Free space priority "
11955         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11956                 head -n1
11957         declare -a AVAIL
11958         free_min_max
11959
11960         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11961         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11962         stack_trap simple_cleanup_common
11963
11964         # Check if we need to generate uneven OSTs
11965         test_mkdir -p $DIR/$tdir/OST${MINI}
11966         local FILL=$((MINV / 4))
11967         local DIFF=$((MAXV - MINV))
11968         local DIFF2=$((DIFF * 100 / MINV))
11969
11970         local threshold=$(do_facet $SINGLEMDS \
11971                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11972         threshold=${threshold%%%}
11973         echo -n "Check for uneven OSTs: "
11974         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11975
11976         if [[ $DIFF2 -gt $threshold ]]; then
11977                 echo "ok"
11978                 echo "Don't need to fill OST$MINI"
11979         else
11980                 # generate uneven OSTs. Write 2% over the QOS threshold value
11981                 echo "no"
11982                 DIFF=$((threshold - DIFF2 + 2))
11983                 DIFF2=$((MINV * DIFF / 100))
11984                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11985                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11986                         error "setstripe failed"
11987                 DIFF=$((DIFF2 / 2048))
11988                 i=0
11989                 while [ $i -lt $DIFF ]; do
11990                         i=$((i + 1))
11991                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11992                                 bs=2M count=1 2>/dev/null
11993                         echo -n .
11994                 done
11995                 echo .
11996                 sync
11997                 sleep_maxage
11998                 free_min_max
11999         fi
12000
12001         DIFF=$((MAXV - MINV))
12002         DIFF2=$((DIFF * 100 / MINV))
12003         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12004         if [ $DIFF2 -gt $threshold ]; then
12005                 echo "ok"
12006         else
12007                 skip "QOS imbalance criteria not met"
12008         fi
12009
12010         MINI1=$MINI
12011         MINV1=$MINV
12012         MAXI1=$MAXI
12013         MAXV1=$MAXV
12014
12015         # now fill using QOS
12016         $LFS setstripe -c 1 $DIR/$tdir
12017         FILL=$((FILL / 200))
12018         if [ $FILL -gt 600 ]; then
12019                 FILL=600
12020         fi
12021         echo "writing $FILL files to QOS-assigned OSTs"
12022         i=0
12023         while [ $i -lt $FILL ]; do
12024                 i=$((i + 1))
12025                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12026                         count=1 2>/dev/null
12027                 echo -n .
12028         done
12029         echo "wrote $i 200k files"
12030         sync
12031         sleep_maxage
12032
12033         echo "Note: free space may not be updated, so measurements might be off"
12034         free_min_max
12035         DIFF2=$((MAXV - MINV))
12036         echo "free space delta: orig $DIFF final $DIFF2"
12037         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12038         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12039         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12040         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12041         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12042         if [[ $DIFF -gt 0 ]]; then
12043                 FILL=$((DIFF2 * 100 / DIFF - 100))
12044                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12045         fi
12046
12047         # Figure out which files were written where
12048         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12049                awk '/'$MINI1': / {print $2; exit}')
12050         echo $UUID
12051         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12052         echo "$MINC files created on smaller OST $MINI1"
12053         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12054                awk '/'$MAXI1': / {print $2; exit}')
12055         echo $UUID
12056         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12057         echo "$MAXC files created on larger OST $MAXI1"
12058         if [[ $MINC -gt 0 ]]; then
12059                 FILL=$((MAXC * 100 / MINC - 100))
12060                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12061         fi
12062         [[ $MAXC -gt $MINC ]] ||
12063                 error_ignore LU-9 "stripe QOS didn't balance free space"
12064 }
12065 run_test 116a "stripe QOS: free space balance ==================="
12066
12067 test_116b() { # LU-2093
12068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12069         remote_mds_nodsh && skip "remote MDS with nodsh"
12070
12071 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12072         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12073                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12074         [ -z "$old_rr" ] && skip "no QOS"
12075         do_facet $SINGLEMDS lctl set_param \
12076                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12077         mkdir -p $DIR/$tdir
12078         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12079         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12080         do_facet $SINGLEMDS lctl set_param fail_loc=0
12081         rm -rf $DIR/$tdir
12082         do_facet $SINGLEMDS lctl set_param \
12083                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12084 }
12085 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12086
12087 test_117() # bug 10891
12088 {
12089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12090
12091         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12092         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12093         lctl set_param fail_loc=0x21e
12094         > $DIR/$tfile || error "truncate failed"
12095         lctl set_param fail_loc=0
12096         echo "Truncate succeeded."
12097         rm -f $DIR/$tfile
12098 }
12099 run_test 117 "verify osd extend =========="
12100
12101 NO_SLOW_RESENDCOUNT=4
12102 export OLD_RESENDCOUNT=""
12103 set_resend_count () {
12104         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12105         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12106         lctl set_param -n $PROC_RESENDCOUNT $1
12107         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12108 }
12109
12110 # for reduce test_118* time (b=14842)
12111 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12112
12113 # Reset async IO behavior after error case
12114 reset_async() {
12115         FILE=$DIR/reset_async
12116
12117         # Ensure all OSCs are cleared
12118         $LFS setstripe -c -1 $FILE
12119         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12120         sync
12121         rm $FILE
12122 }
12123
12124 test_118a() #bug 11710
12125 {
12126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12127
12128         reset_async
12129
12130         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12131         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12132         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12133
12134         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12135                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12136                 return 1;
12137         fi
12138         rm -f $DIR/$tfile
12139 }
12140 run_test 118a "verify O_SYNC works =========="
12141
12142 test_118b()
12143 {
12144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12145         remote_ost_nodsh && skip "remote OST with nodsh"
12146
12147         reset_async
12148
12149         #define OBD_FAIL_SRV_ENOENT 0x217
12150         set_nodes_failloc "$(osts_nodes)" 0x217
12151         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12152         RC=$?
12153         set_nodes_failloc "$(osts_nodes)" 0
12154         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12155         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12156                     grep -c writeback)
12157
12158         if [[ $RC -eq 0 ]]; then
12159                 error "Must return error due to dropped pages, rc=$RC"
12160                 return 1;
12161         fi
12162
12163         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12164                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12165                 return 1;
12166         fi
12167
12168         echo "Dirty pages not leaked on ENOENT"
12169
12170         # Due to the above error the OSC will issue all RPCs syncronously
12171         # until a subsequent RPC completes successfully without error.
12172         $MULTIOP $DIR/$tfile Ow4096yc
12173         rm -f $DIR/$tfile
12174
12175         return 0
12176 }
12177 run_test 118b "Reclaim dirty pages on fatal error =========="
12178
12179 test_118c()
12180 {
12181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12182
12183         # for 118c, restore the original resend count, LU-1940
12184         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12185                                 set_resend_count $OLD_RESENDCOUNT
12186         remote_ost_nodsh && skip "remote OST with nodsh"
12187
12188         reset_async
12189
12190         #define OBD_FAIL_OST_EROFS               0x216
12191         set_nodes_failloc "$(osts_nodes)" 0x216
12192
12193         # multiop should block due to fsync until pages are written
12194         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12195         MULTIPID=$!
12196         sleep 1
12197
12198         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12199                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12200         fi
12201
12202         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12203                     grep -c writeback)
12204         if [[ $WRITEBACK -eq 0 ]]; then
12205                 error "No page in writeback, writeback=$WRITEBACK"
12206         fi
12207
12208         set_nodes_failloc "$(osts_nodes)" 0
12209         wait $MULTIPID
12210         RC=$?
12211         if [[ $RC -ne 0 ]]; then
12212                 error "Multiop fsync failed, rc=$RC"
12213         fi
12214
12215         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12216         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12217                     grep -c writeback)
12218         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12219                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12220         fi
12221
12222         rm -f $DIR/$tfile
12223         echo "Dirty pages flushed via fsync on EROFS"
12224         return 0
12225 }
12226 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12227
12228 # continue to use small resend count to reduce test_118* time (b=14842)
12229 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12230
12231 test_118d()
12232 {
12233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12234         remote_ost_nodsh && skip "remote OST with nodsh"
12235
12236         reset_async
12237
12238         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12239         set_nodes_failloc "$(osts_nodes)" 0x214
12240         # multiop should block due to fsync until pages are written
12241         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12242         MULTIPID=$!
12243         sleep 1
12244
12245         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12246                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12247         fi
12248
12249         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12250                     grep -c writeback)
12251         if [[ $WRITEBACK -eq 0 ]]; then
12252                 error "No page in writeback, writeback=$WRITEBACK"
12253         fi
12254
12255         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12256         set_nodes_failloc "$(osts_nodes)" 0
12257
12258         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12259         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12260                     grep -c writeback)
12261         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12262                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12263         fi
12264
12265         rm -f $DIR/$tfile
12266         echo "Dirty pages gaurenteed flushed via fsync"
12267         return 0
12268 }
12269 run_test 118d "Fsync validation inject a delay of the bulk =========="
12270
12271 test_118f() {
12272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12273
12274         reset_async
12275
12276         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12277         lctl set_param fail_loc=0x8000040a
12278
12279         # Should simulate EINVAL error which is fatal
12280         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12281         RC=$?
12282         if [[ $RC -eq 0 ]]; then
12283                 error "Must return error due to dropped pages, rc=$RC"
12284         fi
12285
12286         lctl set_param fail_loc=0x0
12287
12288         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12289         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12290         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12291                     grep -c writeback)
12292         if [[ $LOCKED -ne 0 ]]; then
12293                 error "Locked pages remain in cache, locked=$LOCKED"
12294         fi
12295
12296         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12297                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12298         fi
12299
12300         rm -f $DIR/$tfile
12301         echo "No pages locked after fsync"
12302
12303         reset_async
12304         return 0
12305 }
12306 run_test 118f "Simulate unrecoverable OSC side error =========="
12307
12308 test_118g() {
12309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12310
12311         reset_async
12312
12313         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12314         lctl set_param fail_loc=0x406
12315
12316         # simulate local -ENOMEM
12317         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12318         RC=$?
12319
12320         lctl set_param fail_loc=0
12321         if [[ $RC -eq 0 ]]; then
12322                 error "Must return error due to dropped pages, rc=$RC"
12323         fi
12324
12325         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12326         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12327         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12328                         grep -c writeback)
12329         if [[ $LOCKED -ne 0 ]]; then
12330                 error "Locked pages remain in cache, locked=$LOCKED"
12331         fi
12332
12333         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12334                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12335         fi
12336
12337         rm -f $DIR/$tfile
12338         echo "No pages locked after fsync"
12339
12340         reset_async
12341         return 0
12342 }
12343 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12344
12345 test_118h() {
12346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12347         remote_ost_nodsh && skip "remote OST with nodsh"
12348
12349         reset_async
12350
12351         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12352         set_nodes_failloc "$(osts_nodes)" 0x20e
12353         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12354         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12355         RC=$?
12356
12357         set_nodes_failloc "$(osts_nodes)" 0
12358         if [[ $RC -eq 0 ]]; then
12359                 error "Must return error due to dropped pages, rc=$RC"
12360         fi
12361
12362         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12363         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12364         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12365                     grep -c writeback)
12366         if [[ $LOCKED -ne 0 ]]; then
12367                 error "Locked pages remain in cache, locked=$LOCKED"
12368         fi
12369
12370         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12371                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12372         fi
12373
12374         rm -f $DIR/$tfile
12375         echo "No pages locked after fsync"
12376
12377         return 0
12378 }
12379 run_test 118h "Verify timeout in handling recoverables errors  =========="
12380
12381 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12382
12383 test_118i() {
12384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12385         remote_ost_nodsh && skip "remote OST with nodsh"
12386
12387         reset_async
12388
12389         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12390         set_nodes_failloc "$(osts_nodes)" 0x20e
12391
12392         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12393         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12394         PID=$!
12395         sleep 5
12396         set_nodes_failloc "$(osts_nodes)" 0
12397
12398         wait $PID
12399         RC=$?
12400         if [[ $RC -ne 0 ]]; then
12401                 error "got error, but should be not, rc=$RC"
12402         fi
12403
12404         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12405         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12406         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12407         if [[ $LOCKED -ne 0 ]]; then
12408                 error "Locked pages remain in cache, locked=$LOCKED"
12409         fi
12410
12411         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12412                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12413         fi
12414
12415         rm -f $DIR/$tfile
12416         echo "No pages locked after fsync"
12417
12418         return 0
12419 }
12420 run_test 118i "Fix error before timeout in recoverable error  =========="
12421
12422 [ "$SLOW" = "no" ] && set_resend_count 4
12423
12424 test_118j() {
12425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12426         remote_ost_nodsh && skip "remote OST with nodsh"
12427
12428         reset_async
12429
12430         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12431         set_nodes_failloc "$(osts_nodes)" 0x220
12432
12433         # return -EIO from OST
12434         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12435         RC=$?
12436         set_nodes_failloc "$(osts_nodes)" 0x0
12437         if [[ $RC -eq 0 ]]; then
12438                 error "Must return error due to dropped pages, rc=$RC"
12439         fi
12440
12441         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12442         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12443         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12444         if [[ $LOCKED -ne 0 ]]; then
12445                 error "Locked pages remain in cache, locked=$LOCKED"
12446         fi
12447
12448         # in recoverable error on OST we want resend and stay until it finished
12449         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12450                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12451         fi
12452
12453         rm -f $DIR/$tfile
12454         echo "No pages locked after fsync"
12455
12456         return 0
12457 }
12458 run_test 118j "Simulate unrecoverable OST side error =========="
12459
12460 test_118k()
12461 {
12462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12463         remote_ost_nodsh && skip "remote OSTs with nodsh"
12464
12465         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12466         set_nodes_failloc "$(osts_nodes)" 0x20e
12467         test_mkdir $DIR/$tdir
12468
12469         for ((i=0;i<10;i++)); do
12470                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12471                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12472                 SLEEPPID=$!
12473                 sleep 0.500s
12474                 kill $SLEEPPID
12475                 wait $SLEEPPID
12476         done
12477
12478         set_nodes_failloc "$(osts_nodes)" 0
12479         rm -rf $DIR/$tdir
12480 }
12481 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12482
12483 test_118l() # LU-646
12484 {
12485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12486
12487         test_mkdir $DIR/$tdir
12488         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12489         rm -rf $DIR/$tdir
12490 }
12491 run_test 118l "fsync dir"
12492
12493 test_118m() # LU-3066
12494 {
12495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12496
12497         test_mkdir $DIR/$tdir
12498         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12499         rm -rf $DIR/$tdir
12500 }
12501 run_test 118m "fdatasync dir ========="
12502
12503 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12504
12505 test_118n()
12506 {
12507         local begin
12508         local end
12509
12510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12511         remote_ost_nodsh && skip "remote OSTs with nodsh"
12512
12513         # Sleep to avoid a cached response.
12514         #define OBD_STATFS_CACHE_SECONDS 1
12515         sleep 2
12516
12517         # Inject a 10 second delay in the OST_STATFS handler.
12518         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12519         set_nodes_failloc "$(osts_nodes)" 0x242
12520
12521         begin=$SECONDS
12522         stat --file-system $MOUNT > /dev/null
12523         end=$SECONDS
12524
12525         set_nodes_failloc "$(osts_nodes)" 0
12526
12527         if ((end - begin > 20)); then
12528             error "statfs took $((end - begin)) seconds, expected 10"
12529         fi
12530 }
12531 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12532
12533 test_119a() # bug 11737
12534 {
12535         BSIZE=$((512 * 1024))
12536         directio write $DIR/$tfile 0 1 $BSIZE
12537         # We ask to read two blocks, which is more than a file size.
12538         # directio will indicate an error when requested and actual
12539         # sizes aren't equeal (a normal situation in this case) and
12540         # print actual read amount.
12541         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12542         if [ "$NOB" != "$BSIZE" ]; then
12543                 error "read $NOB bytes instead of $BSIZE"
12544         fi
12545         rm -f $DIR/$tfile
12546 }
12547 run_test 119a "Short directIO read must return actual read amount"
12548
12549 test_119b() # bug 11737
12550 {
12551         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12552
12553         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12554         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12555         sync
12556         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12557                 error "direct read failed"
12558         rm -f $DIR/$tfile
12559 }
12560 run_test 119b "Sparse directIO read must return actual read amount"
12561
12562 test_119c() # bug 13099
12563 {
12564         BSIZE=1048576
12565         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12566         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12567         rm -f $DIR/$tfile
12568 }
12569 run_test 119c "Testing for direct read hitting hole"
12570
12571 test_119d() # bug 15950
12572 {
12573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12574
12575         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12576         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12577         BSIZE=1048576
12578         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12579         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12580         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12581         lctl set_param fail_loc=0x40d
12582         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12583         pid_dio=$!
12584         sleep 1
12585         cat $DIR/$tfile > /dev/null &
12586         lctl set_param fail_loc=0
12587         pid_reads=$!
12588         wait $pid_dio
12589         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12590         sleep 2
12591         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12592         error "the read rpcs have not completed in 2s"
12593         rm -f $DIR/$tfile
12594         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12595 }
12596 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12597
12598 test_120a() {
12599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12600         remote_mds_nodsh && skip "remote MDS with nodsh"
12601         test_mkdir -i0 -c1 $DIR/$tdir
12602         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12603                 skip_env "no early lock cancel on server"
12604
12605         lru_resize_disable mdc
12606         lru_resize_disable osc
12607         cancel_lru_locks mdc
12608         # asynchronous object destroy at MDT could cause bl ast to client
12609         cancel_lru_locks osc
12610
12611         stat $DIR/$tdir > /dev/null
12612         can1=$(do_facet mds1 \
12613                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12614                awk '/ldlm_cancel/ {print $2}')
12615         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12616                awk '/ldlm_bl_callback/ {print $2}')
12617         test_mkdir -i0 -c1 $DIR/$tdir/d1
12618         can2=$(do_facet mds1 \
12619                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12620                awk '/ldlm_cancel/ {print $2}')
12621         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12622                awk '/ldlm_bl_callback/ {print $2}')
12623         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12624         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12625         lru_resize_enable mdc
12626         lru_resize_enable osc
12627 }
12628 run_test 120a "Early Lock Cancel: mkdir test"
12629
12630 test_120b() {
12631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12632         remote_mds_nodsh && skip "remote MDS with nodsh"
12633         test_mkdir $DIR/$tdir
12634         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12635                 skip_env "no early lock cancel on server"
12636
12637         lru_resize_disable mdc
12638         lru_resize_disable osc
12639         cancel_lru_locks mdc
12640         stat $DIR/$tdir > /dev/null
12641         can1=$(do_facet $SINGLEMDS \
12642                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12643                awk '/ldlm_cancel/ {print $2}')
12644         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12645                awk '/ldlm_bl_callback/ {print $2}')
12646         touch $DIR/$tdir/f1
12647         can2=$(do_facet $SINGLEMDS \
12648                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12649                awk '/ldlm_cancel/ {print $2}')
12650         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12651                awk '/ldlm_bl_callback/ {print $2}')
12652         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12653         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12654         lru_resize_enable mdc
12655         lru_resize_enable osc
12656 }
12657 run_test 120b "Early Lock Cancel: create test"
12658
12659 test_120c() {
12660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12661         remote_mds_nodsh && skip "remote MDS with nodsh"
12662         test_mkdir -i0 -c1 $DIR/$tdir
12663         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12664                 skip "no early lock cancel on server"
12665
12666         lru_resize_disable mdc
12667         lru_resize_disable osc
12668         test_mkdir -i0 -c1 $DIR/$tdir/d1
12669         test_mkdir -i0 -c1 $DIR/$tdir/d2
12670         touch $DIR/$tdir/d1/f1
12671         cancel_lru_locks mdc
12672         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12673         can1=$(do_facet mds1 \
12674                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12675                awk '/ldlm_cancel/ {print $2}')
12676         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12677                awk '/ldlm_bl_callback/ {print $2}')
12678         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12679         can2=$(do_facet mds1 \
12680                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12681                awk '/ldlm_cancel/ {print $2}')
12682         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12683                awk '/ldlm_bl_callback/ {print $2}')
12684         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12685         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12686         lru_resize_enable mdc
12687         lru_resize_enable osc
12688 }
12689 run_test 120c "Early Lock Cancel: link test"
12690
12691 test_120d() {
12692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12693         remote_mds_nodsh && skip "remote MDS with nodsh"
12694         test_mkdir -i0 -c1 $DIR/$tdir
12695         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12696                 skip_env "no early lock cancel on server"
12697
12698         lru_resize_disable mdc
12699         lru_resize_disable osc
12700         touch $DIR/$tdir
12701         cancel_lru_locks mdc
12702         stat $DIR/$tdir > /dev/null
12703         can1=$(do_facet mds1 \
12704                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12705                awk '/ldlm_cancel/ {print $2}')
12706         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12707                awk '/ldlm_bl_callback/ {print $2}')
12708         chmod a+x $DIR/$tdir
12709         can2=$(do_facet mds1 \
12710                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12711                awk '/ldlm_cancel/ {print $2}')
12712         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12713                awk '/ldlm_bl_callback/ {print $2}')
12714         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12715         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12716         lru_resize_enable mdc
12717         lru_resize_enable osc
12718 }
12719 run_test 120d "Early Lock Cancel: setattr test"
12720
12721 test_120e() {
12722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12723         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12724                 skip_env "no early lock cancel on server"
12725         remote_mds_nodsh && skip "remote MDS with nodsh"
12726
12727         local dlmtrace_set=false
12728
12729         test_mkdir -i0 -c1 $DIR/$tdir
12730         lru_resize_disable mdc
12731         lru_resize_disable osc
12732         ! $LCTL get_param debug | grep -q dlmtrace &&
12733                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12734         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12735         cancel_lru_locks mdc
12736         cancel_lru_locks osc
12737         dd if=$DIR/$tdir/f1 of=/dev/null
12738         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12739         # XXX client can not do early lock cancel of OST lock
12740         # during unlink (LU-4206), so cancel osc lock now.
12741         sleep 2
12742         cancel_lru_locks osc
12743         can1=$(do_facet mds1 \
12744                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12745                awk '/ldlm_cancel/ {print $2}')
12746         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12747                awk '/ldlm_bl_callback/ {print $2}')
12748         unlink $DIR/$tdir/f1
12749         sleep 5
12750         can2=$(do_facet mds1 \
12751                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12752                awk '/ldlm_cancel/ {print $2}')
12753         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12754                awk '/ldlm_bl_callback/ {print $2}')
12755         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12756                 $LCTL dk $TMP/cancel.debug.txt
12757         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12758                 $LCTL dk $TMP/blocking.debug.txt
12759         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12760         lru_resize_enable mdc
12761         lru_resize_enable osc
12762 }
12763 run_test 120e "Early Lock Cancel: unlink test"
12764
12765 test_120f() {
12766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12767         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12768                 skip_env "no early lock cancel on server"
12769         remote_mds_nodsh && skip "remote MDS with nodsh"
12770
12771         test_mkdir -i0 -c1 $DIR/$tdir
12772         lru_resize_disable mdc
12773         lru_resize_disable osc
12774         test_mkdir -i0 -c1 $DIR/$tdir/d1
12775         test_mkdir -i0 -c1 $DIR/$tdir/d2
12776         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12777         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12778         cancel_lru_locks mdc
12779         cancel_lru_locks osc
12780         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12781         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12782         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12783         # XXX client can not do early lock cancel of OST lock
12784         # during rename (LU-4206), so cancel osc lock now.
12785         sleep 2
12786         cancel_lru_locks osc
12787         can1=$(do_facet mds1 \
12788                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12789                awk '/ldlm_cancel/ {print $2}')
12790         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12791                awk '/ldlm_bl_callback/ {print $2}')
12792         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12793         sleep 5
12794         can2=$(do_facet mds1 \
12795                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12796                awk '/ldlm_cancel/ {print $2}')
12797         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12798                awk '/ldlm_bl_callback/ {print $2}')
12799         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12800         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12801         lru_resize_enable mdc
12802         lru_resize_enable osc
12803 }
12804 run_test 120f "Early Lock Cancel: rename test"
12805
12806 test_120g() {
12807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12808         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12809                 skip_env "no early lock cancel on server"
12810         remote_mds_nodsh && skip "remote MDS with nodsh"
12811
12812         lru_resize_disable mdc
12813         lru_resize_disable osc
12814         count=10000
12815         echo create $count files
12816         test_mkdir $DIR/$tdir
12817         cancel_lru_locks mdc
12818         cancel_lru_locks osc
12819         t0=$(date +%s)
12820
12821         can0=$(do_facet $SINGLEMDS \
12822                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12823                awk '/ldlm_cancel/ {print $2}')
12824         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12825                awk '/ldlm_bl_callback/ {print $2}')
12826         createmany -o $DIR/$tdir/f $count
12827         sync
12828         can1=$(do_facet $SINGLEMDS \
12829                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12830                awk '/ldlm_cancel/ {print $2}')
12831         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12832                awk '/ldlm_bl_callback/ {print $2}')
12833         t1=$(date +%s)
12834         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12835         echo rm $count files
12836         rm -r $DIR/$tdir
12837         sync
12838         can2=$(do_facet $SINGLEMDS \
12839                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12840                awk '/ldlm_cancel/ {print $2}')
12841         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12842                awk '/ldlm_bl_callback/ {print $2}')
12843         t2=$(date +%s)
12844         echo total: $count removes in $((t2-t1))
12845         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12846         sleep 2
12847         # wait for commitment of removal
12848         lru_resize_enable mdc
12849         lru_resize_enable osc
12850 }
12851 run_test 120g "Early Lock Cancel: performance test"
12852
12853 test_121() { #bug #10589
12854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12855
12856         rm -rf $DIR/$tfile
12857         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12858 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12859         lctl set_param fail_loc=0x310
12860         cancel_lru_locks osc > /dev/null
12861         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12862         lctl set_param fail_loc=0
12863         [[ $reads -eq $writes ]] ||
12864                 error "read $reads blocks, must be $writes blocks"
12865 }
12866 run_test 121 "read cancel race ========="
12867
12868 test_123a_base() { # was test 123, statahead(bug 11401)
12869         local lsx="$1"
12870
12871         SLOWOK=0
12872         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12873                 log "testing UP system. Performance may be lower than expected."
12874                 SLOWOK=1
12875         fi
12876
12877         rm -rf $DIR/$tdir
12878         test_mkdir $DIR/$tdir
12879         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12880         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12881         MULT=10
12882         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12883                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12884
12885                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12886                 lctl set_param -n llite.*.statahead_max 0
12887                 lctl get_param llite.*.statahead_max
12888                 cancel_lru_locks mdc
12889                 cancel_lru_locks osc
12890                 stime=$(date +%s)
12891                 time $lsx $DIR/$tdir | wc -l
12892                 etime=$(date +%s)
12893                 delta=$((etime - stime))
12894                 log "$lsx $i files without statahead: $delta sec"
12895                 lctl set_param llite.*.statahead_max=$max
12896
12897                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12898                         grep "statahead wrong:" | awk '{print $3}')
12899                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12900                 cancel_lru_locks mdc
12901                 cancel_lru_locks osc
12902                 stime=$(date +%s)
12903                 time $lsx $DIR/$tdir | wc -l
12904                 etime=$(date +%s)
12905                 delta_sa=$((etime - stime))
12906                 log "$lsx $i files with statahead: $delta_sa sec"
12907                 lctl get_param -n llite.*.statahead_stats
12908                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12909                         grep "statahead wrong:" | awk '{print $3}')
12910
12911                 [[ $swrong -lt $ewrong ]] &&
12912                         log "statahead was stopped, maybe too many locks held!"
12913                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12914
12915                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12916                         max=$(lctl get_param -n llite.*.statahead_max |
12917                                 head -n 1)
12918                         lctl set_param -n llite.*.statahead_max 0
12919                         lctl get_param llite.*.statahead_max
12920                         cancel_lru_locks mdc
12921                         cancel_lru_locks osc
12922                         stime=$(date +%s)
12923                         time $lsx $DIR/$tdir | wc -l
12924                         etime=$(date +%s)
12925                         delta=$((etime - stime))
12926                         log "$lsx $i files again without statahead: $delta sec"
12927                         lctl set_param llite.*.statahead_max=$max
12928                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12929                                 if [  $SLOWOK -eq 0 ]; then
12930                                         error "$lsx $i files is slower with statahead!"
12931                                 else
12932                                         log "$lsx $i files is slower with statahead!"
12933                                 fi
12934                                 break
12935                         fi
12936                 fi
12937
12938                 [ $delta -gt 20 ] && break
12939                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12940                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12941         done
12942         log "$lsx done"
12943
12944         stime=$(date +%s)
12945         rm -r $DIR/$tdir
12946         sync
12947         etime=$(date +%s)
12948         delta=$((etime - stime))
12949         log "rm -r $DIR/$tdir/: $delta seconds"
12950         log "rm done"
12951         lctl get_param -n llite.*.statahead_stats
12952 }
12953
12954 test_123aa() {
12955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12956
12957         test_123a_base "ls -l"
12958 }
12959 run_test 123aa "verify statahead work"
12960
12961 test_123ab() {
12962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12963
12964         statx_supported || skip_env "Test must be statx() syscall supported"
12965
12966         test_123a_base "$STATX -l"
12967 }
12968 run_test 123ab "verify statahead work by using statx"
12969
12970 test_123ac() {
12971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12972
12973         statx_supported || skip_env "Test must be statx() syscall supported"
12974
12975         local rpcs_before
12976         local rpcs_after
12977         local agl_before
12978         local agl_after
12979
12980         cancel_lru_locks $OSC
12981         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12982         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12983                 awk '/agl.total:/ {print $3}')
12984         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12985         test_123a_base "$STATX --cached=always -D"
12986         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12987                 awk '/agl.total:/ {print $3}')
12988         [ $agl_before -eq $agl_after ] ||
12989                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12990         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12991         [ $rpcs_after -eq $rpcs_before ] ||
12992                 error "$STATX should not send glimpse RPCs to $OSC"
12993 }
12994 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12995
12996 test_123b () { # statahead(bug 15027)
12997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12998
12999         test_mkdir $DIR/$tdir
13000         createmany -o $DIR/$tdir/$tfile-%d 1000
13001
13002         cancel_lru_locks mdc
13003         cancel_lru_locks osc
13004
13005 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13006         lctl set_param fail_loc=0x80000803
13007         ls -lR $DIR/$tdir > /dev/null
13008         log "ls done"
13009         lctl set_param fail_loc=0x0
13010         lctl get_param -n llite.*.statahead_stats
13011         rm -r $DIR/$tdir
13012         sync
13013
13014 }
13015 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13016
13017 test_123c() {
13018         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13019
13020         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13021         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13022         touch $DIR/$tdir.1/{1..3}
13023         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13024
13025         remount_client $MOUNT
13026
13027         $MULTIOP $DIR/$tdir.0 Q
13028
13029         # let statahead to complete
13030         ls -l $DIR/$tdir.0 > /dev/null
13031
13032         testid=$(echo $TESTNAME | tr '_' ' ')
13033         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13034                 error "statahead warning" || true
13035 }
13036 run_test 123c "Can not initialize inode warning on DNE statahead"
13037
13038 test_124a() {
13039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13040         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13041                 skip_env "no lru resize on server"
13042
13043         local NR=2000
13044
13045         test_mkdir $DIR/$tdir
13046
13047         log "create $NR files at $DIR/$tdir"
13048         createmany -o $DIR/$tdir/f $NR ||
13049                 error "failed to create $NR files in $DIR/$tdir"
13050
13051         cancel_lru_locks mdc
13052         ls -l $DIR/$tdir > /dev/null
13053
13054         local NSDIR=""
13055         local LRU_SIZE=0
13056         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13057                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13058                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13059                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13060                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13061                         log "NSDIR=$NSDIR"
13062                         log "NS=$(basename $NSDIR)"
13063                         break
13064                 fi
13065         done
13066
13067         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13068                 skip "Not enough cached locks created!"
13069         fi
13070         log "LRU=$LRU_SIZE"
13071
13072         local SLEEP=30
13073
13074         # We know that lru resize allows one client to hold $LIMIT locks
13075         # for 10h. After that locks begin to be killed by client.
13076         local MAX_HRS=10
13077         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13078         log "LIMIT=$LIMIT"
13079         if [ $LIMIT -lt $LRU_SIZE ]; then
13080                 skip "Limit is too small $LIMIT"
13081         fi
13082
13083         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13084         # killing locks. Some time was spent for creating locks. This means
13085         # that up to the moment of sleep finish we must have killed some of
13086         # them (10-100 locks). This depends on how fast ther were created.
13087         # Many of them were touched in almost the same moment and thus will
13088         # be killed in groups.
13089         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13090
13091         # Use $LRU_SIZE_B here to take into account real number of locks
13092         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13093         local LRU_SIZE_B=$LRU_SIZE
13094         log "LVF=$LVF"
13095         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13096         log "OLD_LVF=$OLD_LVF"
13097         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13098
13099         # Let's make sure that we really have some margin. Client checks
13100         # cached locks every 10 sec.
13101         SLEEP=$((SLEEP+20))
13102         log "Sleep ${SLEEP} sec"
13103         local SEC=0
13104         while ((SEC<$SLEEP)); do
13105                 echo -n "..."
13106                 sleep 5
13107                 SEC=$((SEC+5))
13108                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13109                 echo -n "$LRU_SIZE"
13110         done
13111         echo ""
13112         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13113         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13114
13115         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13116                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13117                 unlinkmany $DIR/$tdir/f $NR
13118                 return
13119         }
13120
13121         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13122         log "unlink $NR files at $DIR/$tdir"
13123         unlinkmany $DIR/$tdir/f $NR
13124 }
13125 run_test 124a "lru resize ======================================="
13126
13127 get_max_pool_limit()
13128 {
13129         local limit=$($LCTL get_param \
13130                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13131         local max=0
13132         for l in $limit; do
13133                 if [[ $l -gt $max ]]; then
13134                         max=$l
13135                 fi
13136         done
13137         echo $max
13138 }
13139
13140 test_124b() {
13141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13142         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13143                 skip_env "no lru resize on server"
13144
13145         LIMIT=$(get_max_pool_limit)
13146
13147         NR=$(($(default_lru_size)*20))
13148         if [[ $NR -gt $LIMIT ]]; then
13149                 log "Limit lock number by $LIMIT locks"
13150                 NR=$LIMIT
13151         fi
13152
13153         IFree=$(mdsrate_inodes_available)
13154         if [ $IFree -lt $NR ]; then
13155                 log "Limit lock number by $IFree inodes"
13156                 NR=$IFree
13157         fi
13158
13159         lru_resize_disable mdc
13160         test_mkdir -p $DIR/$tdir/disable_lru_resize
13161
13162         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13163         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13164         cancel_lru_locks mdc
13165         stime=`date +%s`
13166         PID=""
13167         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13168         PID="$PID $!"
13169         sleep 2
13170         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13171         PID="$PID $!"
13172         sleep 2
13173         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13174         PID="$PID $!"
13175         wait $PID
13176         etime=`date +%s`
13177         nolruresize_delta=$((etime-stime))
13178         log "ls -la time: $nolruresize_delta seconds"
13179         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13180         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13181
13182         lru_resize_enable mdc
13183         test_mkdir -p $DIR/$tdir/enable_lru_resize
13184
13185         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13186         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13187         cancel_lru_locks mdc
13188         stime=`date +%s`
13189         PID=""
13190         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13191         PID="$PID $!"
13192         sleep 2
13193         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13194         PID="$PID $!"
13195         sleep 2
13196         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13197         PID="$PID $!"
13198         wait $PID
13199         etime=`date +%s`
13200         lruresize_delta=$((etime-stime))
13201         log "ls -la time: $lruresize_delta seconds"
13202         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13203
13204         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13205                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13206         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13207                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13208         else
13209                 log "lru resize performs the same with no lru resize"
13210         fi
13211         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13212 }
13213 run_test 124b "lru resize (performance test) ======================="
13214
13215 test_124c() {
13216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13217         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13218                 skip_env "no lru resize on server"
13219
13220         # cache ununsed locks on client
13221         local nr=100
13222         cancel_lru_locks mdc
13223         test_mkdir $DIR/$tdir
13224         createmany -o $DIR/$tdir/f $nr ||
13225                 error "failed to create $nr files in $DIR/$tdir"
13226         ls -l $DIR/$tdir > /dev/null
13227
13228         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13229         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13230         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13231         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13232         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13233
13234         # set lru_max_age to 1 sec
13235         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13236         echo "sleep $((recalc_p * 2)) seconds..."
13237         sleep $((recalc_p * 2))
13238
13239         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13240         # restore lru_max_age
13241         $LCTL set_param -n $nsdir.lru_max_age $max_age
13242         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13243         unlinkmany $DIR/$tdir/f $nr
13244 }
13245 run_test 124c "LRUR cancel very aged locks"
13246
13247 test_124d() {
13248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13249         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13250                 skip_env "no lru resize on server"
13251
13252         # cache ununsed locks on client
13253         local nr=100
13254
13255         lru_resize_disable mdc
13256         stack_trap "lru_resize_enable mdc" EXIT
13257
13258         cancel_lru_locks mdc
13259
13260         # asynchronous object destroy at MDT could cause bl ast to client
13261         test_mkdir $DIR/$tdir
13262         createmany -o $DIR/$tdir/f $nr ||
13263                 error "failed to create $nr files in $DIR/$tdir"
13264         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13265
13266         ls -l $DIR/$tdir > /dev/null
13267
13268         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13269         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13270         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13271         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13272
13273         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13274
13275         # set lru_max_age to 1 sec
13276         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13277         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13278
13279         echo "sleep $((recalc_p * 2)) seconds..."
13280         sleep $((recalc_p * 2))
13281
13282         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13283
13284         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13285 }
13286 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13287
13288 test_125() { # 13358
13289         $LCTL get_param -n llite.*.client_type | grep -q local ||
13290                 skip "must run as local client"
13291         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13292                 skip_env "must have acl enabled"
13293         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13294
13295         test_mkdir $DIR/$tdir
13296         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13297         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13298         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13299 }
13300 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13301
13302 test_126() { # bug 12829/13455
13303         $GSS && skip_env "must run as gss disabled"
13304         $LCTL get_param -n llite.*.client_type | grep -q local ||
13305                 skip "must run as local client"
13306         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13307
13308         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13309         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13310         rm -f $DIR/$tfile
13311         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13312 }
13313 run_test 126 "check that the fsgid provided by the client is taken into account"
13314
13315 test_127a() { # bug 15521
13316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13317         local name count samp unit min max sum sumsq
13318
13319         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13320         echo "stats before reset"
13321         $LCTL get_param osc.*.stats
13322         $LCTL set_param osc.*.stats=0
13323         local fsize=$((2048 * 1024))
13324
13325         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13326         cancel_lru_locks osc
13327         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13328
13329         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13330         stack_trap "rm -f $TMP/$tfile.tmp"
13331         while read name count samp unit min max sum sumsq; do
13332                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13333                 [ ! $min ] && error "Missing min value for $name proc entry"
13334                 eval $name=$count || error "Wrong proc format"
13335
13336                 case $name in
13337                 read_bytes|write_bytes)
13338                         [[ "$unit" =~ "bytes" ]] ||
13339                                 error "unit is not 'bytes': $unit"
13340                         (( $min >= 4096 )) || error "min is too small: $min"
13341                         (( $min <= $fsize )) || error "min is too big: $min"
13342                         (( $max >= 4096 )) || error "max is too small: $max"
13343                         (( $max <= $fsize )) || error "max is too big: $max"
13344                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13345                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13346                                 error "sumsquare is too small: $sumsq"
13347                         (( $sumsq <= $fsize * $fsize )) ||
13348                                 error "sumsquare is too big: $sumsq"
13349                         ;;
13350                 ost_read|ost_write)
13351                         [[ "$unit" =~ "usec" ]] ||
13352                                 error "unit is not 'usec': $unit"
13353                         ;;
13354                 *)      ;;
13355                 esac
13356         done < $DIR/$tfile.tmp
13357
13358         #check that we actually got some stats
13359         [ "$read_bytes" ] || error "Missing read_bytes stats"
13360         [ "$write_bytes" ] || error "Missing write_bytes stats"
13361         [ "$read_bytes" != 0 ] || error "no read done"
13362         [ "$write_bytes" != 0 ] || error "no write done"
13363 }
13364 run_test 127a "verify the client stats are sane"
13365
13366 test_127b() { # bug LU-333
13367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13368         local name count samp unit min max sum sumsq
13369
13370         echo "stats before reset"
13371         $LCTL get_param llite.*.stats
13372         $LCTL set_param llite.*.stats=0
13373
13374         # perform 2 reads and writes so MAX is different from SUM.
13375         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13376         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13377         cancel_lru_locks osc
13378         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13379         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13380
13381         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13382         stack_trap "rm -f $TMP/$tfile.tmp"
13383         while read name count samp unit min max sum sumsq; do
13384                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13385                 eval $name=$count || error "Wrong proc format"
13386
13387                 case $name in
13388                 read_bytes|write_bytes)
13389                         [[ "$unit" =~ "bytes" ]] ||
13390                                 error "unit is not 'bytes': $unit"
13391                         (( $count == 2 )) || error "count is not 2: $count"
13392                         (( $min == $PAGE_SIZE )) ||
13393                                 error "min is not $PAGE_SIZE: $min"
13394                         (( $max == $PAGE_SIZE )) ||
13395                                 error "max is not $PAGE_SIZE: $max"
13396                         (( $sum == $PAGE_SIZE * 2 )) ||
13397                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13398                         ;;
13399                 read|write)
13400                         [[ "$unit" =~ "usec" ]] ||
13401                                 error "unit is not 'usec': $unit"
13402                         ;;
13403                 *)      ;;
13404                 esac
13405         done < $TMP/$tfile.tmp
13406
13407         #check that we actually got some stats
13408         [ "$read_bytes" ] || error "Missing read_bytes stats"
13409         [ "$write_bytes" ] || error "Missing write_bytes stats"
13410         [ "$read_bytes" != 0 ] || error "no read done"
13411         [ "$write_bytes" != 0 ] || error "no write done"
13412 }
13413 run_test 127b "verify the llite client stats are sane"
13414
13415 test_127c() { # LU-12394
13416         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13417         local size
13418         local bsize
13419         local reads
13420         local writes
13421         local count
13422
13423         $LCTL set_param llite.*.extents_stats=1
13424         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13425
13426         # Use two stripes so there is enough space in default config
13427         $LFS setstripe -c 2 $DIR/$tfile
13428
13429         # Extent stats start at 0-4K and go in power of two buckets
13430         # LL_HIST_START = 12 --> 2^12 = 4K
13431         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13432         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13433         # small configs
13434         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13435                 do
13436                 # Write and read, 2x each, second time at a non-zero offset
13437                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13438                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13439                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13440                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13441                 rm -f $DIR/$tfile
13442         done
13443
13444         $LCTL get_param llite.*.extents_stats
13445
13446         count=2
13447         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13448                 do
13449                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13450                                 grep -m 1 $bsize)
13451                 reads=$(echo $bucket | awk '{print $5}')
13452                 writes=$(echo $bucket | awk '{print $9}')
13453                 [ "$reads" -eq $count ] ||
13454                         error "$reads reads in < $bsize bucket, expect $count"
13455                 [ "$writes" -eq $count ] ||
13456                         error "$writes writes in < $bsize bucket, expect $count"
13457         done
13458
13459         # Test mmap write and read
13460         $LCTL set_param llite.*.extents_stats=c
13461         size=512
13462         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13463         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13464         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13465
13466         $LCTL get_param llite.*.extents_stats
13467
13468         count=$(((size*1024) / PAGE_SIZE))
13469
13470         bsize=$((2 * PAGE_SIZE / 1024))K
13471
13472         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         # mmap writes fault in the page first, creating an additonal read
13477         [ "$reads" -eq $((2 * count)) ] ||
13478                 error "$reads reads in < $bsize bucket, expect $count"
13479         [ "$writes" -eq $count ] ||
13480                 error "$writes writes in < $bsize bucket, expect $count"
13481 }
13482 run_test 127c "test llite extent stats with regular & mmap i/o"
13483
13484 test_128() { # bug 15212
13485         touch $DIR/$tfile
13486         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13487                 find $DIR/$tfile
13488                 find $DIR/$tfile
13489         EOF
13490
13491         result=$(grep error $TMP/$tfile.log)
13492         rm -f $DIR/$tfile $TMP/$tfile.log
13493         [ -z "$result" ] ||
13494                 error "consecutive find's under interactive lfs failed"
13495 }
13496 run_test 128 "interactive lfs for 2 consecutive find's"
13497
13498 set_dir_limits () {
13499         local mntdev
13500         local canondev
13501         local node
13502
13503         local ldproc=/proc/fs/ldiskfs
13504         local facets=$(get_facets MDS)
13505
13506         for facet in ${facets//,/ }; do
13507                 canondev=$(ldiskfs_canon \
13508                            *.$(convert_facet2label $facet).mntdev $facet)
13509                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13510                         ldproc=/sys/fs/ldiskfs
13511                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13512                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13513         done
13514 }
13515
13516 check_mds_dmesg() {
13517         local facets=$(get_facets MDS)
13518         for facet in ${facets//,/ }; do
13519                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13520         done
13521         return 1
13522 }
13523
13524 test_129() {
13525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13526         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13527                 skip "Need MDS version with at least 2.5.56"
13528         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13529                 skip_env "ldiskfs only test"
13530         fi
13531         remote_mds_nodsh && skip "remote MDS with nodsh"
13532
13533         local ENOSPC=28
13534         local has_warning=false
13535
13536         rm -rf $DIR/$tdir
13537         mkdir -p $DIR/$tdir
13538
13539         # block size of mds1
13540         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13541         set_dir_limits $maxsize $((maxsize * 6 / 8))
13542         stack_trap "set_dir_limits 0 0"
13543         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13544         local dirsize=$(stat -c%s "$DIR/$tdir")
13545         local nfiles=0
13546         while (( $dirsize <= $maxsize )); do
13547                 $MCREATE $DIR/$tdir/file_base_$nfiles
13548                 rc=$?
13549                 # check two errors:
13550                 # ENOSPC for ext4 max_dir_size, which has been used since
13551                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13552                 if (( rc == ENOSPC )); then
13553                         set_dir_limits 0 0
13554                         echo "rc=$rc returned as expected after $nfiles files"
13555
13556                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13557                                 error "create failed w/o dir size limit"
13558
13559                         # messages may be rate limited if test is run repeatedly
13560                         check_mds_dmesg '"is approaching max"' ||
13561                                 echo "warning message should be output"
13562                         check_mds_dmesg '"has reached max"' ||
13563                                 echo "reached message should be output"
13564
13565                         dirsize=$(stat -c%s "$DIR/$tdir")
13566
13567                         [[ $dirsize -ge $maxsize ]] && return 0
13568                         error "dirsize $dirsize < $maxsize after $nfiles files"
13569                 elif (( rc != 0 )); then
13570                         break
13571                 fi
13572                 nfiles=$((nfiles + 1))
13573                 dirsize=$(stat -c%s "$DIR/$tdir")
13574         done
13575
13576         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13577 }
13578 run_test 129 "test directory size limit ========================"
13579
13580 OLDIFS="$IFS"
13581 cleanup_130() {
13582         trap 0
13583         IFS="$OLDIFS"
13584 }
13585
13586 test_130a() {
13587         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13588         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13589
13590         trap cleanup_130 EXIT RETURN
13591
13592         local fm_file=$DIR/$tfile
13593         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13594         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13595                 error "dd failed for $fm_file"
13596
13597         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13598         filefrag -ves $fm_file
13599         RC=$?
13600         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13601                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13602         [ $RC != 0 ] && error "filefrag $fm_file failed"
13603
13604         filefrag_op=$(filefrag -ve -k $fm_file |
13605                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13606         lun=$($LFS getstripe -i $fm_file)
13607
13608         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13609         IFS=$'\n'
13610         tot_len=0
13611         for line in $filefrag_op
13612         do
13613                 frag_lun=`echo $line | cut -d: -f5`
13614                 ext_len=`echo $line | cut -d: -f4`
13615                 if (( $frag_lun != $lun )); then
13616                         cleanup_130
13617                         error "FIEMAP on 1-stripe file($fm_file) failed"
13618                         return
13619                 fi
13620                 (( tot_len += ext_len ))
13621         done
13622
13623         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13624                 cleanup_130
13625                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13626                 return
13627         fi
13628
13629         cleanup_130
13630
13631         echo "FIEMAP on single striped file succeeded"
13632 }
13633 run_test 130a "FIEMAP (1-stripe file)"
13634
13635 test_130b() {
13636         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13637
13638         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13639         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13640
13641         trap cleanup_130 EXIT RETURN
13642
13643         local fm_file=$DIR/$tfile
13644         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13645                         error "setstripe on $fm_file"
13646         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13647                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13648
13649         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13650                 error "dd failed on $fm_file"
13651
13652         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13653         filefrag_op=$(filefrag -ve -k $fm_file |
13654                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13655
13656         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13657                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13658
13659         IFS=$'\n'
13660         tot_len=0
13661         num_luns=1
13662         for line in $filefrag_op
13663         do
13664                 frag_lun=$(echo $line | cut -d: -f5 |
13665                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13666                 ext_len=$(echo $line | cut -d: -f4)
13667                 if (( $frag_lun != $last_lun )); then
13668                         if (( tot_len != 1024 )); then
13669                                 cleanup_130
13670                                 error "FIEMAP on $fm_file failed; returned " \
13671                                 "len $tot_len for OST $last_lun instead of 1024"
13672                                 return
13673                         else
13674                                 (( num_luns += 1 ))
13675                                 tot_len=0
13676                         fi
13677                 fi
13678                 (( tot_len += ext_len ))
13679                 last_lun=$frag_lun
13680         done
13681         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13682                 cleanup_130
13683                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13684                         "luns or wrong len for OST $last_lun"
13685                 return
13686         fi
13687
13688         cleanup_130
13689
13690         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13691 }
13692 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13693
13694 test_130c() {
13695         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13696
13697         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13698         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13699
13700         trap cleanup_130 EXIT RETURN
13701
13702         local fm_file=$DIR/$tfile
13703         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13704         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13705                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13706
13707         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13708                         error "dd failed on $fm_file"
13709
13710         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13711         filefrag_op=$(filefrag -ve -k $fm_file |
13712                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13713
13714         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13715                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13716
13717         IFS=$'\n'
13718         tot_len=0
13719         num_luns=1
13720         for line in $filefrag_op
13721         do
13722                 frag_lun=$(echo $line | cut -d: -f5 |
13723                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13724                 ext_len=$(echo $line | cut -d: -f4)
13725                 if (( $frag_lun != $last_lun )); then
13726                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13727                         if (( logical != 512 )); then
13728                                 cleanup_130
13729                                 error "FIEMAP on $fm_file failed; returned " \
13730                                 "logical start for lun $logical instead of 512"
13731                                 return
13732                         fi
13733                         if (( tot_len != 512 )); then
13734                                 cleanup_130
13735                                 error "FIEMAP on $fm_file failed; returned " \
13736                                 "len $tot_len for OST $last_lun instead of 1024"
13737                                 return
13738                         else
13739                                 (( num_luns += 1 ))
13740                                 tot_len=0
13741                         fi
13742                 fi
13743                 (( tot_len += ext_len ))
13744                 last_lun=$frag_lun
13745         done
13746         if (( num_luns != 2 || tot_len != 512 )); then
13747                 cleanup_130
13748                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13749                         "luns or wrong len for OST $last_lun"
13750                 return
13751         fi
13752
13753         cleanup_130
13754
13755         echo "FIEMAP on 2-stripe file with hole succeeded"
13756 }
13757 run_test 130c "FIEMAP (2-stripe file with hole)"
13758
13759 test_130d() {
13760         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13761
13762         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13763         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13764
13765         trap cleanup_130 EXIT RETURN
13766
13767         local fm_file=$DIR/$tfile
13768         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13769                         error "setstripe on $fm_file"
13770         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13771                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13772
13773         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13774         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13775                 error "dd failed on $fm_file"
13776
13777         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13778         filefrag_op=$(filefrag -ve -k $fm_file |
13779                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13780
13781         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13782                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13783
13784         IFS=$'\n'
13785         tot_len=0
13786         num_luns=1
13787         for line in $filefrag_op
13788         do
13789                 frag_lun=$(echo $line | cut -d: -f5 |
13790                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13791                 ext_len=$(echo $line | cut -d: -f4)
13792                 if (( $frag_lun != $last_lun )); then
13793                         if (( tot_len != 1024 )); then
13794                                 cleanup_130
13795                                 error "FIEMAP on $fm_file failed; returned " \
13796                                 "len $tot_len for OST $last_lun instead of 1024"
13797                                 return
13798                         else
13799                                 (( num_luns += 1 ))
13800                                 tot_len=0
13801                         fi
13802                 fi
13803                 (( tot_len += ext_len ))
13804                 last_lun=$frag_lun
13805         done
13806         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13807                 cleanup_130
13808                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13809                         "luns or wrong len for OST $last_lun"
13810                 return
13811         fi
13812
13813         cleanup_130
13814
13815         echo "FIEMAP on N-stripe file succeeded"
13816 }
13817 run_test 130d "FIEMAP (N-stripe file)"
13818
13819 test_130e() {
13820         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13821
13822         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13823         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13824
13825         trap cleanup_130 EXIT RETURN
13826
13827         local fm_file=$DIR/$tfile
13828         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13829
13830         NUM_BLKS=512
13831         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13832         for ((i = 0; i < $NUM_BLKS; i++)); do
13833                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13834                         conv=notrunc > /dev/null 2>&1
13835         done
13836
13837         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13838         filefrag_op=$(filefrag -ve -k $fm_file |
13839                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13840
13841         last_lun=$(echo $filefrag_op | cut -d: -f5)
13842
13843         IFS=$'\n'
13844         tot_len=0
13845         num_luns=1
13846         for line in $filefrag_op; do
13847                 frag_lun=$(echo $line | cut -d: -f5)
13848                 ext_len=$(echo $line | cut -d: -f4)
13849                 if [[ "$frag_lun" != "$last_lun" ]]; then
13850                         if (( tot_len != $EXPECTED_LEN )); then
13851                                 cleanup_130
13852                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13853                         else
13854                                 (( num_luns += 1 ))
13855                                 tot_len=0
13856                         fi
13857                 fi
13858                 (( tot_len += ext_len ))
13859                 last_lun=$frag_lun
13860         done
13861         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13862                 cleanup_130
13863                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13864         fi
13865
13866         echo "FIEMAP with continuation calls succeeded"
13867 }
13868 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13869
13870 test_130f() {
13871         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13872         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13873
13874         local fm_file=$DIR/$tfile
13875         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13876                 error "multiop create with lov_delay_create on $fm_file"
13877
13878         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13879         filefrag_extents=$(filefrag -vek $fm_file |
13880                            awk '/extents? found/ { print $2 }')
13881         if [[ "$filefrag_extents" != "0" ]]; then
13882                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13883         fi
13884
13885         rm -f $fm_file
13886 }
13887 run_test 130f "FIEMAP (unstriped file)"
13888
13889 test_130g() {
13890         local file=$DIR/$tfile
13891         local nr=$((OSTCOUNT * 100))
13892
13893         $LFS setstripe -C $nr $file ||
13894                 error "failed to setstripe -C $nr $file"
13895
13896         dd if=/dev/zero of=$file count=$nr bs=1M
13897         sync
13898         nr=$($LFS getstripe -c $file)
13899
13900         local extents=$(filefrag -v $file |
13901                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13902
13903         echo "filefrag list $extents extents in file with stripecount $nr"
13904         if (( extents < nr )); then
13905                 $LFS getstripe $file
13906                 filefrag -v $file
13907                 error "filefrag printed $extents < $nr extents"
13908         fi
13909
13910         rm -f $file
13911 }
13912 run_test 130g "FIEMAP (overstripe file)"
13913
13914 # Test for writev/readv
13915 test_131a() {
13916         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13917                 error "writev test failed"
13918         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13919                 error "readv failed"
13920         rm -f $DIR/$tfile
13921 }
13922 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13923
13924 test_131b() {
13925         local fsize=$((524288 + 1048576 + 1572864))
13926         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13927                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13928                         error "append writev test failed"
13929
13930         ((fsize += 1572864 + 1048576))
13931         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13932                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13933                         error "append writev test failed"
13934         rm -f $DIR/$tfile
13935 }
13936 run_test 131b "test append writev"
13937
13938 test_131c() {
13939         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13940         error "NOT PASS"
13941 }
13942 run_test 131c "test read/write on file w/o objects"
13943
13944 test_131d() {
13945         rwv -f $DIR/$tfile -w -n 1 1572864
13946         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13947         if [ "$NOB" != 1572864 ]; then
13948                 error "Short read filed: read $NOB bytes instead of 1572864"
13949         fi
13950         rm -f $DIR/$tfile
13951 }
13952 run_test 131d "test short read"
13953
13954 test_131e() {
13955         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13956         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13957         error "read hitting hole failed"
13958         rm -f $DIR/$tfile
13959 }
13960 run_test 131e "test read hitting hole"
13961
13962 check_stats() {
13963         local facet=$1
13964         local op=$2
13965         local want=${3:-0}
13966         local res
13967
13968         case $facet in
13969         mds*) res=$(do_facet $facet \
13970                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13971                  ;;
13972         ost*) res=$(do_facet $facet \
13973                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13974                  ;;
13975         *) error "Wrong facet '$facet'" ;;
13976         esac
13977         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13978         # if the argument $3 is zero, it means any stat increment is ok.
13979         if [[ $want -gt 0 ]]; then
13980                 local count=$(echo $res | awk '{ print $2 }')
13981                 [[ $count -ne $want ]] &&
13982                         error "The $op counter on $facet is $count, not $want"
13983         fi
13984 }
13985
13986 test_133a() {
13987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13988         remote_ost_nodsh && skip "remote OST with nodsh"
13989         remote_mds_nodsh && skip "remote MDS with nodsh"
13990         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13991                 skip_env "MDS doesn't support rename stats"
13992
13993         local testdir=$DIR/${tdir}/stats_testdir
13994
13995         mkdir -p $DIR/${tdir}
13996
13997         # clear stats.
13998         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13999         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14000
14001         # verify mdt stats first.
14002         mkdir ${testdir} || error "mkdir failed"
14003         check_stats $SINGLEMDS "mkdir" 1
14004         touch ${testdir}/${tfile} || error "touch failed"
14005         check_stats $SINGLEMDS "open" 1
14006         check_stats $SINGLEMDS "close" 1
14007         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14008                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14009                 check_stats $SINGLEMDS "mknod" 2
14010         }
14011         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14012         check_stats $SINGLEMDS "unlink" 1
14013         rm -f ${testdir}/${tfile} || error "file remove failed"
14014         check_stats $SINGLEMDS "unlink" 2
14015
14016         # remove working dir and check mdt stats again.
14017         rmdir ${testdir} || error "rmdir failed"
14018         check_stats $SINGLEMDS "rmdir" 1
14019
14020         local testdir1=$DIR/${tdir}/stats_testdir1
14021         mkdir -p ${testdir}
14022         mkdir -p ${testdir1}
14023         touch ${testdir1}/test1
14024         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14025         check_stats $SINGLEMDS "crossdir_rename" 1
14026
14027         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14028         check_stats $SINGLEMDS "samedir_rename" 1
14029
14030         rm -rf $DIR/${tdir}
14031 }
14032 run_test 133a "Verifying MDT stats ========================================"
14033
14034 test_133b() {
14035         local res
14036
14037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14038         remote_ost_nodsh && skip "remote OST with nodsh"
14039         remote_mds_nodsh && skip "remote MDS with nodsh"
14040
14041         local testdir=$DIR/${tdir}/stats_testdir
14042
14043         mkdir -p ${testdir} || error "mkdir failed"
14044         touch ${testdir}/${tfile} || error "touch failed"
14045         cancel_lru_locks mdc
14046
14047         # clear stats.
14048         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14049         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14050
14051         # extra mdt stats verification.
14052         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14053         check_stats $SINGLEMDS "setattr" 1
14054         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14055         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14056         then            # LU-1740
14057                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14058                 check_stats $SINGLEMDS "getattr" 1
14059         fi
14060         rm -rf $DIR/${tdir}
14061
14062         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14063         # so the check below is not reliable
14064         [ $MDSCOUNT -eq 1 ] || return 0
14065
14066         # Sleep to avoid a cached response.
14067         #define OBD_STATFS_CACHE_SECONDS 1
14068         sleep 2
14069         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14070         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14071         $LFS df || error "lfs failed"
14072         check_stats $SINGLEMDS "statfs" 1
14073
14074         # check aggregated statfs (LU-10018)
14075         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14076                 return 0
14077         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14078                 return 0
14079         sleep 2
14080         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14081         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14082         df $DIR
14083         check_stats $SINGLEMDS "statfs" 1
14084
14085         # We want to check that the client didn't send OST_STATFS to
14086         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14087         # extra care is needed here.
14088         if remote_mds; then
14089                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14090                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14091
14092                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14093                 [ "$res" ] && error "OST got STATFS"
14094         fi
14095
14096         return 0
14097 }
14098 run_test 133b "Verifying extra MDT stats =================================="
14099
14100 test_133c() {
14101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14102         remote_ost_nodsh && skip "remote OST with nodsh"
14103         remote_mds_nodsh && skip "remote MDS with nodsh"
14104
14105         local testdir=$DIR/$tdir/stats_testdir
14106
14107         test_mkdir -p $testdir
14108
14109         # verify obdfilter stats.
14110         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14111         sync
14112         cancel_lru_locks osc
14113         wait_delete_completed
14114
14115         # clear stats.
14116         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14117         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14118
14119         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14120                 error "dd failed"
14121         sync
14122         cancel_lru_locks osc
14123         check_stats ost1 "write" 1
14124
14125         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14126         check_stats ost1 "read" 1
14127
14128         > $testdir/$tfile || error "truncate failed"
14129         check_stats ost1 "punch" 1
14130
14131         rm -f $testdir/$tfile || error "file remove failed"
14132         wait_delete_completed
14133         check_stats ost1 "destroy" 1
14134
14135         rm -rf $DIR/$tdir
14136 }
14137 run_test 133c "Verifying OST stats ========================================"
14138
14139 order_2() {
14140         local value=$1
14141         local orig=$value
14142         local order=1
14143
14144         while [ $value -ge 2 ]; do
14145                 order=$((order*2))
14146                 value=$((value/2))
14147         done
14148
14149         if [ $orig -gt $order ]; then
14150                 order=$((order*2))
14151         fi
14152         echo $order
14153 }
14154
14155 size_in_KMGT() {
14156     local value=$1
14157     local size=('K' 'M' 'G' 'T');
14158     local i=0
14159     local size_string=$value
14160
14161     while [ $value -ge 1024 ]; do
14162         if [ $i -gt 3 ]; then
14163             #T is the biggest unit we get here, if that is bigger,
14164             #just return XXXT
14165             size_string=${value}T
14166             break
14167         fi
14168         value=$((value >> 10))
14169         if [ $value -lt 1024 ]; then
14170             size_string=${value}${size[$i]}
14171             break
14172         fi
14173         i=$((i + 1))
14174     done
14175
14176     echo $size_string
14177 }
14178
14179 get_rename_size() {
14180         local size=$1
14181         local context=${2:-.}
14182         local sample=$(do_facet $SINGLEMDS $LCTL \
14183                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14184                 grep -A1 $context |
14185                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14186         echo $sample
14187 }
14188
14189 test_133d() {
14190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14191         remote_ost_nodsh && skip "remote OST with nodsh"
14192         remote_mds_nodsh && skip "remote MDS with nodsh"
14193         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14194                 skip_env "MDS doesn't support rename stats"
14195
14196         local testdir1=$DIR/${tdir}/stats_testdir1
14197         local testdir2=$DIR/${tdir}/stats_testdir2
14198         mkdir -p $DIR/${tdir}
14199
14200         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14201
14202         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14203         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14204
14205         createmany -o $testdir1/test 512 || error "createmany failed"
14206
14207         # check samedir rename size
14208         mv ${testdir1}/test0 ${testdir1}/test_0
14209
14210         local testdir1_size=$(ls -l $DIR/${tdir} |
14211                 awk '/stats_testdir1/ {print $5}')
14212         local testdir2_size=$(ls -l $DIR/${tdir} |
14213                 awk '/stats_testdir2/ {print $5}')
14214
14215         testdir1_size=$(order_2 $testdir1_size)
14216         testdir2_size=$(order_2 $testdir2_size)
14217
14218         testdir1_size=$(size_in_KMGT $testdir1_size)
14219         testdir2_size=$(size_in_KMGT $testdir2_size)
14220
14221         echo "source rename dir size: ${testdir1_size}"
14222         echo "target rename dir size: ${testdir2_size}"
14223
14224         local cmd="do_facet $SINGLEMDS $LCTL "
14225         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14226
14227         eval $cmd || error "$cmd failed"
14228         local samedir=$($cmd | grep 'same_dir')
14229         local same_sample=$(get_rename_size $testdir1_size)
14230         [ -z "$samedir" ] && error "samedir_rename_size count error"
14231         [[ $same_sample -eq 1 ]] ||
14232                 error "samedir_rename_size error $same_sample"
14233         echo "Check same dir rename stats success"
14234
14235         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14236
14237         # check crossdir rename size
14238         mv ${testdir1}/test_0 ${testdir2}/test_0
14239
14240         testdir1_size=$(ls -l $DIR/${tdir} |
14241                 awk '/stats_testdir1/ {print $5}')
14242         testdir2_size=$(ls -l $DIR/${tdir} |
14243                 awk '/stats_testdir2/ {print $5}')
14244
14245         testdir1_size=$(order_2 $testdir1_size)
14246         testdir2_size=$(order_2 $testdir2_size)
14247
14248         testdir1_size=$(size_in_KMGT $testdir1_size)
14249         testdir2_size=$(size_in_KMGT $testdir2_size)
14250
14251         echo "source rename dir size: ${testdir1_size}"
14252         echo "target rename dir size: ${testdir2_size}"
14253
14254         eval $cmd || error "$cmd failed"
14255         local crossdir=$($cmd | grep 'crossdir')
14256         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14257         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14258         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14259         [[ $src_sample -eq 1 ]] ||
14260                 error "crossdir_rename_size error $src_sample"
14261         [[ $tgt_sample -eq 1 ]] ||
14262                 error "crossdir_rename_size error $tgt_sample"
14263         echo "Check cross dir rename stats success"
14264         rm -rf $DIR/${tdir}
14265 }
14266 run_test 133d "Verifying rename_stats ========================================"
14267
14268 test_133e() {
14269         remote_mds_nodsh && skip "remote MDS with nodsh"
14270         remote_ost_nodsh && skip "remote OST with nodsh"
14271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14272
14273         local testdir=$DIR/${tdir}/stats_testdir
14274         local ctr f0 f1 bs=32768 count=42 sum
14275
14276         mkdir -p ${testdir} || error "mkdir failed"
14277
14278         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14279
14280         for ctr in {write,read}_bytes; do
14281                 sync
14282                 cancel_lru_locks osc
14283
14284                 do_facet ost1 $LCTL set_param -n \
14285                         "obdfilter.*.exports.clear=clear"
14286
14287                 if [ $ctr = write_bytes ]; then
14288                         f0=/dev/zero
14289                         f1=${testdir}/${tfile}
14290                 else
14291                         f0=${testdir}/${tfile}
14292                         f1=/dev/null
14293                 fi
14294
14295                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14296                         error "dd failed"
14297                 sync
14298                 cancel_lru_locks osc
14299
14300                 sum=$(do_facet ost1 $LCTL get_param \
14301                         "obdfilter.*.exports.*.stats" |
14302                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14303                                 $1 == ctr { sum += $7 }
14304                                 END { printf("%0.0f", sum) }')
14305
14306                 if ((sum != bs * count)); then
14307                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14308                 fi
14309         done
14310
14311         rm -rf $DIR/${tdir}
14312 }
14313 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14314
14315 test_133f() {
14316         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14317                 skip "too old lustre for get_param -R ($facet_ver)"
14318
14319         # verifying readability.
14320         $LCTL get_param -R '*' &> /dev/null
14321
14322         # Verifing writability with badarea_io.
14323         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14324         local skipped_params='force_lbug|changelog_mask|daemon_file'
14325         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14326                 egrep -v "$skipped_params" |
14327                 xargs -n 1 find $proc_dirs -name |
14328                 xargs -n 1 badarea_io ||
14329                 error "client badarea_io failed"
14330
14331         # remount the FS in case writes/reads /proc break the FS
14332         cleanup || error "failed to unmount"
14333         setup || error "failed to setup"
14334 }
14335 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14336
14337 test_133g() {
14338         remote_mds_nodsh && skip "remote MDS with nodsh"
14339         remote_ost_nodsh && skip "remote OST with nodsh"
14340
14341         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14342         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14343         local facet
14344         for facet in mds1 ost1; do
14345                 local facet_ver=$(lustre_version_code $facet)
14346                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14347                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14348                 else
14349                         log "$facet: too old lustre for get_param -R"
14350                 fi
14351                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14352                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14353                                 tr -d = | egrep -v $skipped_params |
14354                                 xargs -n 1 find $proc_dirs -name |
14355                                 xargs -n 1 badarea_io" ||
14356                                         error "$facet badarea_io failed"
14357                 else
14358                         skip_noexit "$facet: too old lustre for get_param -R"
14359                 fi
14360         done
14361
14362         # remount the FS in case writes/reads /proc break the FS
14363         cleanup || error "failed to unmount"
14364         setup || error "failed to setup"
14365 }
14366 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14367
14368 test_133h() {
14369         remote_mds_nodsh && skip "remote MDS with nodsh"
14370         remote_ost_nodsh && skip "remote OST with nodsh"
14371         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14372                 skip "Need MDS version at least 2.9.54"
14373
14374         local facet
14375         for facet in client mds1 ost1; do
14376                 # Get the list of files that are missing the terminating newline
14377                 local plist=$(do_facet $facet
14378                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14379                 local ent
14380                 for ent in $plist; do
14381                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14382                                 awk -v FS='\v' -v RS='\v\v' \
14383                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14384                                         print FILENAME}'" 2>/dev/null)
14385                         [ -z $missing ] || {
14386                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14387                                 error "file does not end with newline: $facet-$ent"
14388                         }
14389                 done
14390         done
14391 }
14392 run_test 133h "Proc files should end with newlines"
14393
14394 test_134a() {
14395         remote_mds_nodsh && skip "remote MDS with nodsh"
14396         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14397                 skip "Need MDS version at least 2.7.54"
14398
14399         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14400         cancel_lru_locks mdc
14401
14402         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14403         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14404         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14405
14406         local nr=1000
14407         createmany -o $DIR/$tdir/f $nr ||
14408                 error "failed to create $nr files in $DIR/$tdir"
14409         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14410
14411         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14412         do_facet mds1 $LCTL set_param fail_loc=0x327
14413         do_facet mds1 $LCTL set_param fail_val=500
14414         touch $DIR/$tdir/m
14415
14416         echo "sleep 10 seconds ..."
14417         sleep 10
14418         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14419
14420         do_facet mds1 $LCTL set_param fail_loc=0
14421         do_facet mds1 $LCTL set_param fail_val=0
14422         [ $lck_cnt -lt $unused ] ||
14423                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14424
14425         rm $DIR/$tdir/m
14426         unlinkmany $DIR/$tdir/f $nr
14427 }
14428 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14429
14430 test_134b() {
14431         remote_mds_nodsh && skip "remote MDS with nodsh"
14432         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14433                 skip "Need MDS version at least 2.7.54"
14434
14435         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14436         cancel_lru_locks mdc
14437
14438         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14439                         ldlm.lock_reclaim_threshold_mb)
14440         # disable reclaim temporarily
14441         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14442
14443         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14444         do_facet mds1 $LCTL set_param fail_loc=0x328
14445         do_facet mds1 $LCTL set_param fail_val=500
14446
14447         $LCTL set_param debug=+trace
14448
14449         local nr=600
14450         createmany -o $DIR/$tdir/f $nr &
14451         local create_pid=$!
14452
14453         echo "Sleep $TIMEOUT seconds ..."
14454         sleep $TIMEOUT
14455         if ! ps -p $create_pid  > /dev/null 2>&1; then
14456                 do_facet mds1 $LCTL set_param fail_loc=0
14457                 do_facet mds1 $LCTL set_param fail_val=0
14458                 do_facet mds1 $LCTL set_param \
14459                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14460                 error "createmany finished incorrectly!"
14461         fi
14462         do_facet mds1 $LCTL set_param fail_loc=0
14463         do_facet mds1 $LCTL set_param fail_val=0
14464         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14465         wait $create_pid || return 1
14466
14467         unlinkmany $DIR/$tdir/f $nr
14468 }
14469 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14470
14471 test_135() {
14472         remote_mds_nodsh && skip "remote MDS with nodsh"
14473         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14474                 skip "Need MDS version at least 2.13.50"
14475         local fname
14476
14477         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14478
14479 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14480         #set only one record at plain llog
14481         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14482
14483         #fill already existed plain llog each 64767
14484         #wrapping whole catalog
14485         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14486
14487         createmany -o $DIR/$tdir/$tfile_ 64700
14488         for (( i = 0; i < 64700; i = i + 2 ))
14489         do
14490                 rm $DIR/$tdir/$tfile_$i &
14491                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14492                 local pid=$!
14493                 wait $pid
14494         done
14495
14496         #waiting osp synchronization
14497         wait_delete_completed
14498 }
14499 run_test 135 "Race catalog processing"
14500
14501 test_136() {
14502         remote_mds_nodsh && skip "remote MDS with nodsh"
14503         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14504                 skip "Need MDS version at least 2.13.50"
14505         local fname
14506
14507         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14508         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14509         #set only one record at plain llog
14510 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14511         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14512
14513         #fill already existed 2 plain llogs each 64767
14514         #wrapping whole catalog
14515         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14516         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14517         wait_delete_completed
14518
14519         createmany -o $DIR/$tdir/$tfile_ 10
14520         sleep 25
14521
14522         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14523         for (( i = 0; i < 10; i = i + 3 ))
14524         do
14525                 rm $DIR/$tdir/$tfile_$i &
14526                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14527                 local pid=$!
14528                 wait $pid
14529                 sleep 7
14530                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14531         done
14532
14533         #waiting osp synchronization
14534         wait_delete_completed
14535 }
14536 run_test 136 "Race catalog processing 2"
14537
14538 test_140() { #bug-17379
14539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14540
14541         test_mkdir $DIR/$tdir
14542         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14543         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14544
14545         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14546         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14547         local i=0
14548         while i=$((i + 1)); do
14549                 test_mkdir $i
14550                 cd $i || error "Changing to $i"
14551                 ln -s ../stat stat || error "Creating stat symlink"
14552                 # Read the symlink until ELOOP present,
14553                 # not LBUGing the system is considered success,
14554                 # we didn't overrun the stack.
14555                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14556                 if [ $ret -ne 0 ]; then
14557                         if [ $ret -eq 40 ]; then
14558                                 break  # -ELOOP
14559                         else
14560                                 error "Open stat symlink"
14561                                         return
14562                         fi
14563                 fi
14564         done
14565         i=$((i - 1))
14566         echo "The symlink depth = $i"
14567         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14568                 error "Invalid symlink depth"
14569
14570         # Test recursive symlink
14571         ln -s symlink_self symlink_self
14572         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14573         echo "open symlink_self returns $ret"
14574         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14575 }
14576 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14577
14578 test_150a() {
14579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14580
14581         local TF="$TMP/$tfile"
14582
14583         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14584         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14585         cp $TF $DIR/$tfile
14586         cancel_lru_locks $OSC
14587         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14588         remount_client $MOUNT
14589         df -P $MOUNT
14590         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14591
14592         $TRUNCATE $TF 6000
14593         $TRUNCATE $DIR/$tfile 6000
14594         cancel_lru_locks $OSC
14595         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14596
14597         echo "12345" >>$TF
14598         echo "12345" >>$DIR/$tfile
14599         cancel_lru_locks $OSC
14600         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14601
14602         echo "12345" >>$TF
14603         echo "12345" >>$DIR/$tfile
14604         cancel_lru_locks $OSC
14605         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14606 }
14607 run_test 150a "truncate/append tests"
14608
14609 test_150b() {
14610         check_set_fallocate_or_skip
14611
14612         touch $DIR/$tfile
14613         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14614         check_fallocate $DIR/$tfile || skip_eopnotsupp "fallocate failed"
14615 }
14616 run_test 150b "Verify fallocate (prealloc) functionality"
14617
14618 test_150bb() {
14619         check_set_fallocate_or_skip
14620
14621         touch $DIR/$tfile
14622         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14623         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14624         > $DIR/$tfile
14625         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14626         # precomputed md5sum for 20MB of zeroes
14627         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14628         local sum=($(md5sum $DIR/$tfile))
14629
14630         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14631
14632         check_set_fallocate 1
14633
14634         > $DIR/$tfile
14635         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14636         sum=($(md5sum $DIR/$tfile))
14637
14638         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14639 }
14640 run_test 150bb "Verify fallocate modes both zero space"
14641
14642 test_150c() {
14643         check_set_fallocate_or_skip
14644         local striping="-c2"
14645
14646         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14647         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14648         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14649         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14650         local want=$((OSTCOUNT * 1048576))
14651
14652         # Must allocate all requested space, not more than 5% extra
14653         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14654                 error "bytes $bytes is not $want"
14655
14656         rm -f $DIR/$tfile
14657
14658         echo "verify fallocate on PFL file"
14659
14660         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14661
14662         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14663                 error "Create $DIR/$tfile failed"
14664         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
14665         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14666         want=$((512 * 1048576))
14667
14668         # Must allocate all requested space, not more than 5% extra
14669         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14670                 error "bytes $bytes is not $want"
14671 }
14672 run_test 150c "Verify fallocate Size and Blocks"
14673
14674 test_150d() {
14675         check_set_fallocate_or_skip
14676         local striping="-c2"
14677
14678         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14679
14680         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14681         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14682                 error "setstripe failed"
14683         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14684         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14685         local want=$((OSTCOUNT * 1048576))
14686
14687         # Must allocate all requested space, not more than 5% extra
14688         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14689                 error "bytes $bytes is not $want"
14690 }
14691 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14692
14693 test_150e() {
14694         check_set_fallocate_or_skip
14695
14696         echo "df before:"
14697         $LFS df
14698         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14699         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14700                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14701
14702         # Find OST with Minimum Size
14703         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14704                        sort -un | head -1)
14705
14706         # Get 100MB per OST of the available space to reduce run time
14707         # else 60% of the available space if we are running SLOW tests
14708         if [ $SLOW == "no" ]; then
14709                 local space=$((1024 * 100 * OSTCOUNT))
14710         else
14711                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14712         fi
14713
14714         fallocate -l${space}k $DIR/$tfile ||
14715                 error "fallocate ${space}k $DIR/$tfile failed"
14716         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14717
14718         # get size immediately after fallocate. This should be correctly
14719         # updated
14720         local size=$(stat -c '%s' $DIR/$tfile)
14721         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14722
14723         # Sleep for a while for statfs to get updated. And not pull from cache.
14724         sleep 2
14725
14726         echo "df after fallocate:"
14727         $LFS df
14728
14729         (( size / 1024 == space )) || error "size $size != requested $space"
14730         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14731                 error "used $used < space $space"
14732
14733         rm $DIR/$tfile || error "rm failed"
14734         sync
14735         wait_delete_completed
14736
14737         echo "df after unlink:"
14738         $LFS df
14739 }
14740 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14741
14742 test_150f() {
14743         local size
14744         local blocks
14745         local want_size_before=20480 # in bytes
14746         local want_blocks_before=40 # 512 sized blocks
14747         local want_blocks_after=24  # 512 sized blocks
14748         local length=$(((want_blocks_before - want_blocks_after) * 512))
14749
14750         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14751                 skip "need at least 2.14.0 for fallocate punch"
14752
14753         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14754                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14755         fi
14756
14757         check_set_fallocate_or_skip
14758         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14759
14760         [[ "x$DOM" == "xyes" ]] &&
14761                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14762
14763         echo "Verify fallocate punch: Range within the file range"
14764         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14765                 error "dd failed for bs 4096 and count 5"
14766
14767         # Call fallocate with punch range which is within the file range
14768         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
14769                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
14770         # client must see changes immediately after fallocate
14771         size=$(stat -c '%s' $DIR/$tfile)
14772         blocks=$(stat -c '%b' $DIR/$tfile)
14773
14774         # Verify punch worked.
14775         (( blocks == want_blocks_after )) ||
14776                 error "punch failed: blocks $blocks != $want_blocks_after"
14777
14778         (( size == want_size_before )) ||
14779                 error "punch failed: size $size != $want_size_before"
14780
14781         # Verify there is hole in file
14782         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14783         # precomputed md5sum
14784         local expect="4a9a834a2db02452929c0a348273b4aa"
14785
14786         cksum=($(md5sum $DIR/$tfile))
14787         [[ "${cksum[0]}" == "$expect" ]] ||
14788                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14789
14790         # Start second sub-case for fallocate punch.
14791         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14792         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14793                 error "dd failed for bs 4096 and count 5"
14794
14795         # Punch range less than block size will have no change in block count
14796         want_blocks_after=40  # 512 sized blocks
14797
14798         # Punch overlaps two blocks and less than blocksize
14799         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
14800                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
14801         size=$(stat -c '%s' $DIR/$tfile)
14802         blocks=$(stat -c '%b' $DIR/$tfile)
14803
14804         # Verify punch worked.
14805         (( blocks == want_blocks_after )) ||
14806                 error "punch failed: blocks $blocks != $want_blocks_after"
14807
14808         (( size == want_size_before )) ||
14809                 error "punch failed: size $size != $want_size_before"
14810
14811         # Verify if range is really zero'ed out. We expect Zeros.
14812         # precomputed md5sum
14813         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14814         cksum=($(md5sum $DIR/$tfile))
14815         [[ "${cksum[0]}" == "$expect" ]] ||
14816                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14817 }
14818 run_test 150f "Verify fallocate punch functionality"
14819
14820 test_150g() {
14821         local space
14822         local size
14823         local blocks
14824         local blocks_after
14825         local size_after
14826         local BS=4096 # Block size in bytes
14827
14828         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14829                 skip "need at least 2.14.0 for fallocate punch"
14830
14831         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14832                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14833         fi
14834
14835         check_set_fallocate_or_skip
14836         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14837
14838         if [[ "x$DOM" == "xyes" ]]; then
14839                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14840                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14841         else
14842                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14843                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14844         fi
14845
14846         # Get 100MB per OST of the available space to reduce run time
14847         # else 60% of the available space if we are running SLOW tests
14848         if [ $SLOW == "no" ]; then
14849                 space=$((1024 * 100 * OSTCOUNT))
14850         else
14851                 # Find OST with Minimum Size
14852                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14853                         sort -un | head -1)
14854                 echo "min size OST: $space"
14855                 space=$(((space * 60)/100 * OSTCOUNT))
14856         fi
14857         # space in 1k units, round to 4k blocks
14858         local blkcount=$((space * 1024 / $BS))
14859
14860         echo "Verify fallocate punch: Very large Range"
14861         fallocate -l${space}k $DIR/$tfile ||
14862                 error "fallocate ${space}k $DIR/$tfile failed"
14863         # write 1M at the end, start and in the middle
14864         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14865                 error "dd failed: bs $BS count 256"
14866         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14867                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14868         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14869                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14870
14871         # Gather stats.
14872         size=$(stat -c '%s' $DIR/$tfile)
14873
14874         # gather punch length.
14875         local punch_size=$((size - (BS * 2)))
14876
14877         echo "punch_size = $punch_size"
14878         echo "size - punch_size: $((size - punch_size))"
14879         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14880
14881         # Call fallocate to punch all except 2 blocks. We leave the
14882         # first and the last block
14883         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14884         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
14885                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
14886
14887         size_after=$(stat -c '%s' $DIR/$tfile)
14888         blocks_after=$(stat -c '%b' $DIR/$tfile)
14889
14890         # Verify punch worked.
14891         # Size should be kept
14892         (( size == size_after )) ||
14893                 error "punch failed: size $size != $size_after"
14894
14895         # two 4k data blocks to remain plus possible 1 extra extent block
14896         (( blocks_after <= ((BS / 512) * 3) )) ||
14897                 error "too many blocks remains: $blocks_after"
14898
14899         # Verify that file has hole between the first and the last blocks
14900         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14901         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14902
14903         echo "Hole at [$hole_start, $hole_end)"
14904         (( hole_start == BS )) ||
14905                 error "no hole at offset $BS after punch"
14906
14907         (( hole_end == BS + punch_size )) ||
14908                 error "data at offset $hole_end < $((BS + punch_size))"
14909 }
14910 run_test 150g "Verify fallocate punch on large range"
14911
14912 #LU-2902 roc_hit was not able to read all values from lproc
14913 function roc_hit_init() {
14914         local list=$(comma_list $(osts_nodes))
14915         local dir=$DIR/$tdir-check
14916         local file=$dir/$tfile
14917         local BEFORE
14918         local AFTER
14919         local idx
14920
14921         test_mkdir $dir
14922         #use setstripe to do a write to every ost
14923         for i in $(seq 0 $((OSTCOUNT-1))); do
14924                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14925                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14926                 idx=$(printf %04x $i)
14927                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14928                         awk '$1 == "cache_access" {sum += $7}
14929                                 END { printf("%0.0f", sum) }')
14930
14931                 cancel_lru_locks osc
14932                 cat $file >/dev/null
14933
14934                 AFTER=$(get_osd_param $list *OST*$idx stats |
14935                         awk '$1 == "cache_access" {sum += $7}
14936                                 END { printf("%0.0f", sum) }')
14937
14938                 echo BEFORE:$BEFORE AFTER:$AFTER
14939                 if ! let "AFTER - BEFORE == 4"; then
14940                         rm -rf $dir
14941                         error "roc_hit is not safe to use"
14942                 fi
14943                 rm $file
14944         done
14945
14946         rm -rf $dir
14947 }
14948
14949 function roc_hit() {
14950         local list=$(comma_list $(osts_nodes))
14951         echo $(get_osd_param $list '' stats |
14952                 awk '$1 == "cache_hit" {sum += $7}
14953                         END { printf("%0.0f", sum) }')
14954 }
14955
14956 function set_cache() {
14957         local on=1
14958
14959         if [ "$2" == "off" ]; then
14960                 on=0;
14961         fi
14962         local list=$(comma_list $(osts_nodes))
14963         set_osd_param $list '' $1_cache_enable $on
14964
14965         cancel_lru_locks osc
14966 }
14967
14968 test_151() {
14969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14970         remote_ost_nodsh && skip "remote OST with nodsh"
14971
14972         local CPAGES=3
14973         local list=$(comma_list $(osts_nodes))
14974
14975         # check whether obdfilter is cache capable at all
14976         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14977                 skip "not cache-capable obdfilter"
14978         fi
14979
14980         # check cache is enabled on all obdfilters
14981         if get_osd_param $list '' read_cache_enable | grep 0; then
14982                 skip "oss cache is disabled"
14983         fi
14984
14985         set_osd_param $list '' writethrough_cache_enable 1
14986
14987         # check write cache is enabled on all obdfilters
14988         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14989                 skip "oss write cache is NOT enabled"
14990         fi
14991
14992         roc_hit_init
14993
14994         #define OBD_FAIL_OBD_NO_LRU  0x609
14995         do_nodes $list $LCTL set_param fail_loc=0x609
14996
14997         # pages should be in the case right after write
14998         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14999                 error "dd failed"
15000
15001         local BEFORE=$(roc_hit)
15002         cancel_lru_locks osc
15003         cat $DIR/$tfile >/dev/null
15004         local AFTER=$(roc_hit)
15005
15006         do_nodes $list $LCTL set_param fail_loc=0
15007
15008         if ! let "AFTER - BEFORE == CPAGES"; then
15009                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15010         fi
15011
15012         cancel_lru_locks osc
15013         # invalidates OST cache
15014         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15015         set_osd_param $list '' read_cache_enable 0
15016         cat $DIR/$tfile >/dev/null
15017
15018         # now data shouldn't be found in the cache
15019         BEFORE=$(roc_hit)
15020         cancel_lru_locks osc
15021         cat $DIR/$tfile >/dev/null
15022         AFTER=$(roc_hit)
15023         if let "AFTER - BEFORE != 0"; then
15024                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15025         fi
15026
15027         set_osd_param $list '' read_cache_enable 1
15028         rm -f $DIR/$tfile
15029 }
15030 run_test 151 "test cache on oss and controls ==============================="
15031
15032 test_152() {
15033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15034
15035         local TF="$TMP/$tfile"
15036
15037         # simulate ENOMEM during write
15038 #define OBD_FAIL_OST_NOMEM      0x226
15039         lctl set_param fail_loc=0x80000226
15040         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15041         cp $TF $DIR/$tfile
15042         sync || error "sync failed"
15043         lctl set_param fail_loc=0
15044
15045         # discard client's cache
15046         cancel_lru_locks osc
15047
15048         # simulate ENOMEM during read
15049         lctl set_param fail_loc=0x80000226
15050         cmp $TF $DIR/$tfile || error "cmp failed"
15051         lctl set_param fail_loc=0
15052
15053         rm -f $TF
15054 }
15055 run_test 152 "test read/write with enomem ============================"
15056
15057 test_153() {
15058         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15059 }
15060 run_test 153 "test if fdatasync does not crash ======================="
15061
15062 dot_lustre_fid_permission_check() {
15063         local fid=$1
15064         local ffid=$MOUNT/.lustre/fid/$fid
15065         local test_dir=$2
15066
15067         echo "stat fid $fid"
15068         stat $ffid > /dev/null || error "stat $ffid failed."
15069         echo "touch fid $fid"
15070         touch $ffid || error "touch $ffid failed."
15071         echo "write to fid $fid"
15072         cat /etc/hosts > $ffid || error "write $ffid failed."
15073         echo "read fid $fid"
15074         diff /etc/hosts $ffid || error "read $ffid failed."
15075         echo "append write to fid $fid"
15076         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15077         echo "rename fid $fid"
15078         mv $ffid $test_dir/$tfile.1 &&
15079                 error "rename $ffid to $tfile.1 should fail."
15080         touch $test_dir/$tfile.1
15081         mv $test_dir/$tfile.1 $ffid &&
15082                 error "rename $tfile.1 to $ffid should fail."
15083         rm -f $test_dir/$tfile.1
15084         echo "truncate fid $fid"
15085         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15086         echo "link fid $fid"
15087         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15088         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15089                 echo "setfacl fid $fid"
15090                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15091                 echo "getfacl fid $fid"
15092                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15093         fi
15094         echo "unlink fid $fid"
15095         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15096         echo "mknod fid $fid"
15097         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15098
15099         fid=[0xf00000400:0x1:0x0]
15100         ffid=$MOUNT/.lustre/fid/$fid
15101
15102         echo "stat non-exist fid $fid"
15103         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15104         echo "write to non-exist fid $fid"
15105         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15106         echo "link new fid $fid"
15107         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15108
15109         mkdir -p $test_dir/$tdir
15110         touch $test_dir/$tdir/$tfile
15111         fid=$($LFS path2fid $test_dir/$tdir)
15112         rc=$?
15113         [ $rc -ne 0 ] &&
15114                 error "error: could not get fid for $test_dir/$dir/$tfile."
15115
15116         ffid=$MOUNT/.lustre/fid/$fid
15117
15118         echo "ls $fid"
15119         ls $ffid > /dev/null || error "ls $ffid failed."
15120         echo "touch $fid/$tfile.1"
15121         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15122
15123         echo "touch $MOUNT/.lustre/fid/$tfile"
15124         touch $MOUNT/.lustre/fid/$tfile && \
15125                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15126
15127         echo "setxattr to $MOUNT/.lustre/fid"
15128         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15129
15130         echo "listxattr for $MOUNT/.lustre/fid"
15131         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15132
15133         echo "delxattr from $MOUNT/.lustre/fid"
15134         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15135
15136         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15137         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15138                 error "touch invalid fid should fail."
15139
15140         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15141         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15142                 error "touch non-normal fid should fail."
15143
15144         echo "rename $tdir to $MOUNT/.lustre/fid"
15145         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15146                 error "rename to $MOUNT/.lustre/fid should fail."
15147
15148         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15149         then            # LU-3547
15150                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15151                 local new_obf_mode=777
15152
15153                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15154                 chmod $new_obf_mode $DIR/.lustre/fid ||
15155                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15156
15157                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15158                 [ $obf_mode -eq $new_obf_mode ] ||
15159                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15160
15161                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15162                 chmod $old_obf_mode $DIR/.lustre/fid ||
15163                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15164         fi
15165
15166         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15167         fid=$($LFS path2fid $test_dir/$tfile-2)
15168
15169         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15170         then # LU-5424
15171                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15172                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15173                         error "create lov data thru .lustre failed"
15174         fi
15175         echo "cp /etc/passwd $test_dir/$tfile-2"
15176         cp /etc/passwd $test_dir/$tfile-2 ||
15177                 error "copy to $test_dir/$tfile-2 failed."
15178         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15179         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15180                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15181
15182         rm -rf $test_dir/tfile.lnk
15183         rm -rf $test_dir/$tfile-2
15184 }
15185
15186 test_154A() {
15187         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15188                 skip "Need MDS version at least 2.4.1"
15189
15190         local tf=$DIR/$tfile
15191         touch $tf
15192
15193         local fid=$($LFS path2fid $tf)
15194         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15195
15196         # check that we get the same pathname back
15197         local rootpath
15198         local found
15199         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15200                 echo "$rootpath $fid"
15201                 found=$($LFS fid2path $rootpath "$fid")
15202                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15203                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15204         done
15205
15206         # check wrong root path format
15207         rootpath=$MOUNT"_wrong"
15208         found=$($LFS fid2path $rootpath "$fid")
15209         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15210 }
15211 run_test 154A "lfs path2fid and fid2path basic checks"
15212
15213 test_154B() {
15214         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15215                 skip "Need MDS version at least 2.4.1"
15216
15217         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15218         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15219         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15220         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15221
15222         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15223         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15224
15225         # check that we get the same pathname
15226         echo "PFID: $PFID, name: $name"
15227         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15228         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15229         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15230                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15231
15232         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15233 }
15234 run_test 154B "verify the ll_decode_linkea tool"
15235
15236 test_154a() {
15237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15238         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15239         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15240                 skip "Need MDS version at least 2.2.51"
15241         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15242
15243         cp /etc/hosts $DIR/$tfile
15244
15245         fid=$($LFS path2fid $DIR/$tfile)
15246         rc=$?
15247         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15248
15249         dot_lustre_fid_permission_check "$fid" $DIR ||
15250                 error "dot lustre permission check $fid failed"
15251
15252         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15253
15254         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15255
15256         touch $MOUNT/.lustre/file &&
15257                 error "creation is not allowed under .lustre"
15258
15259         mkdir $MOUNT/.lustre/dir &&
15260                 error "mkdir is not allowed under .lustre"
15261
15262         rm -rf $DIR/$tfile
15263 }
15264 run_test 154a "Open-by-FID"
15265
15266 test_154b() {
15267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15268         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15269         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15270         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15271                 skip "Need MDS version at least 2.2.51"
15272
15273         local remote_dir=$DIR/$tdir/remote_dir
15274         local MDTIDX=1
15275         local rc=0
15276
15277         mkdir -p $DIR/$tdir
15278         $LFS mkdir -i $MDTIDX $remote_dir ||
15279                 error "create remote directory failed"
15280
15281         cp /etc/hosts $remote_dir/$tfile
15282
15283         fid=$($LFS path2fid $remote_dir/$tfile)
15284         rc=$?
15285         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15286
15287         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15288                 error "dot lustre permission check $fid failed"
15289         rm -rf $DIR/$tdir
15290 }
15291 run_test 154b "Open-by-FID for remote directory"
15292
15293 test_154c() {
15294         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15295                 skip "Need MDS version at least 2.4.1"
15296
15297         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15298         local FID1=$($LFS path2fid $DIR/$tfile.1)
15299         local FID2=$($LFS path2fid $DIR/$tfile.2)
15300         local FID3=$($LFS path2fid $DIR/$tfile.3)
15301
15302         local N=1
15303         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15304                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15305                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15306                 local want=FID$N
15307                 [ "$FID" = "${!want}" ] ||
15308                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15309                 N=$((N + 1))
15310         done
15311
15312         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15313         do
15314                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15315                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15316                 N=$((N + 1))
15317         done
15318 }
15319 run_test 154c "lfs path2fid and fid2path multiple arguments"
15320
15321 test_154d() {
15322         remote_mds_nodsh && skip "remote MDS with nodsh"
15323         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15324                 skip "Need MDS version at least 2.5.53"
15325
15326         if remote_mds; then
15327                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15328         else
15329                 nid="0@lo"
15330         fi
15331         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15332         local fd
15333         local cmd
15334
15335         rm -f $DIR/$tfile
15336         touch $DIR/$tfile
15337
15338         local fid=$($LFS path2fid $DIR/$tfile)
15339         # Open the file
15340         fd=$(free_fd)
15341         cmd="exec $fd<$DIR/$tfile"
15342         eval $cmd
15343         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15344         echo "$fid_list" | grep "$fid"
15345         rc=$?
15346
15347         cmd="exec $fd>/dev/null"
15348         eval $cmd
15349         if [ $rc -ne 0 ]; then
15350                 error "FID $fid not found in open files list $fid_list"
15351         fi
15352 }
15353 run_test 154d "Verify open file fid"
15354
15355 test_154e()
15356 {
15357         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15358                 skip "Need MDS version at least 2.6.50"
15359
15360         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15361                 error ".lustre returned by readdir"
15362         fi
15363 }
15364 run_test 154e ".lustre is not returned by readdir"
15365
15366 test_154f() {
15367         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15368
15369         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15370         mkdir_on_mdt0 $DIR/$tdir
15371         # test dirs inherit from its stripe
15372         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15373         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15374         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15375         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15376         touch $DIR/f
15377
15378         # get fid of parents
15379         local FID0=$($LFS path2fid $DIR/$tdir)
15380         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15381         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15382         local FID3=$($LFS path2fid $DIR)
15383
15384         # check that path2fid --parents returns expected <parent_fid>/name
15385         # 1) test for a directory (single parent)
15386         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15387         [ "$parent" == "$FID0/foo1" ] ||
15388                 error "expected parent: $FID0/foo1, got: $parent"
15389
15390         # 2) test for a file with nlink > 1 (multiple parents)
15391         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15392         echo "$parent" | grep -F "$FID1/$tfile" ||
15393                 error "$FID1/$tfile not returned in parent list"
15394         echo "$parent" | grep -F "$FID2/link" ||
15395                 error "$FID2/link not returned in parent list"
15396
15397         # 3) get parent by fid
15398         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15399         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15400         echo "$parent" | grep -F "$FID1/$tfile" ||
15401                 error "$FID1/$tfile not returned in parent list (by fid)"
15402         echo "$parent" | grep -F "$FID2/link" ||
15403                 error "$FID2/link not returned in parent list (by fid)"
15404
15405         # 4) test for entry in root directory
15406         parent=$($LFS path2fid --parents $DIR/f)
15407         echo "$parent" | grep -F "$FID3/f" ||
15408                 error "$FID3/f not returned in parent list"
15409
15410         # 5) test it on root directory
15411         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15412                 error "$MOUNT should not have parents"
15413
15414         # enable xattr caching and check that linkea is correctly updated
15415         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15416         save_lustre_params client "llite.*.xattr_cache" > $save
15417         lctl set_param llite.*.xattr_cache 1
15418
15419         # 6.1) linkea update on rename
15420         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15421
15422         # get parents by fid
15423         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15424         # foo1 should no longer be returned in parent list
15425         echo "$parent" | grep -F "$FID1" &&
15426                 error "$FID1 should no longer be in parent list"
15427         # the new path should appear
15428         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15429                 error "$FID2/$tfile.moved is not in parent list"
15430
15431         # 6.2) linkea update on unlink
15432         rm -f $DIR/$tdir/foo2/link
15433         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15434         # foo2/link should no longer be returned in parent list
15435         echo "$parent" | grep -F "$FID2/link" &&
15436                 error "$FID2/link should no longer be in parent list"
15437         true
15438
15439         rm -f $DIR/f
15440         restore_lustre_params < $save
15441         rm -f $save
15442 }
15443 run_test 154f "get parent fids by reading link ea"
15444
15445 test_154g()
15446 {
15447         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15448         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15449            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15450                 skip "Need MDS version at least 2.6.92"
15451
15452         mkdir_on_mdt0 $DIR/$tdir
15453         llapi_fid_test -d $DIR/$tdir
15454 }
15455 run_test 154g "various llapi FID tests"
15456
15457 test_155_small_load() {
15458     local temp=$TMP/$tfile
15459     local file=$DIR/$tfile
15460
15461     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15462         error "dd of=$temp bs=6096 count=1 failed"
15463     cp $temp $file
15464     cancel_lru_locks $OSC
15465     cmp $temp $file || error "$temp $file differ"
15466
15467     $TRUNCATE $temp 6000
15468     $TRUNCATE $file 6000
15469     cmp $temp $file || error "$temp $file differ (truncate1)"
15470
15471     echo "12345" >>$temp
15472     echo "12345" >>$file
15473     cmp $temp $file || error "$temp $file differ (append1)"
15474
15475     echo "12345" >>$temp
15476     echo "12345" >>$file
15477     cmp $temp $file || error "$temp $file differ (append2)"
15478
15479     rm -f $temp $file
15480     true
15481 }
15482
15483 test_155_big_load() {
15484         remote_ost_nodsh && skip "remote OST with nodsh"
15485
15486         local temp=$TMP/$tfile
15487         local file=$DIR/$tfile
15488
15489         free_min_max
15490         local cache_size=$(do_facet ost$((MAXI+1)) \
15491                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15492         local large_file_size=$((cache_size * 2))
15493
15494         echo "OSS cache size: $cache_size KB"
15495         echo "Large file size: $large_file_size KB"
15496
15497         [ $MAXV -le $large_file_size ] &&
15498                 skip_env "max available OST size needs > $large_file_size KB"
15499
15500         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15501
15502         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15503                 error "dd of=$temp bs=$large_file_size count=1k failed"
15504         cp $temp $file
15505         ls -lh $temp $file
15506         cancel_lru_locks osc
15507         cmp $temp $file || error "$temp $file differ"
15508
15509         rm -f $temp $file
15510         true
15511 }
15512
15513 save_writethrough() {
15514         local facets=$(get_facets OST)
15515
15516         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15517 }
15518
15519 test_155a() {
15520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15521
15522         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15523
15524         save_writethrough $p
15525
15526         set_cache read on
15527         set_cache writethrough on
15528         test_155_small_load
15529         restore_lustre_params < $p
15530         rm -f $p
15531 }
15532 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15533
15534 test_155b() {
15535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15536
15537         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15538
15539         save_writethrough $p
15540
15541         set_cache read on
15542         set_cache writethrough off
15543         test_155_small_load
15544         restore_lustre_params < $p
15545         rm -f $p
15546 }
15547 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15548
15549 test_155c() {
15550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15551
15552         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15553
15554         save_writethrough $p
15555
15556         set_cache read off
15557         set_cache writethrough on
15558         test_155_small_load
15559         restore_lustre_params < $p
15560         rm -f $p
15561 }
15562 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15563
15564 test_155d() {
15565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15566
15567         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15568
15569         save_writethrough $p
15570
15571         set_cache read off
15572         set_cache writethrough off
15573         test_155_small_load
15574         restore_lustre_params < $p
15575         rm -f $p
15576 }
15577 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15578
15579 test_155e() {
15580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15581
15582         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15583
15584         save_writethrough $p
15585
15586         set_cache read on
15587         set_cache writethrough on
15588         test_155_big_load
15589         restore_lustre_params < $p
15590         rm -f $p
15591 }
15592 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15593
15594 test_155f() {
15595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15596
15597         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15598
15599         save_writethrough $p
15600
15601         set_cache read on
15602         set_cache writethrough off
15603         test_155_big_load
15604         restore_lustre_params < $p
15605         rm -f $p
15606 }
15607 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15608
15609 test_155g() {
15610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15611
15612         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15613
15614         save_writethrough $p
15615
15616         set_cache read off
15617         set_cache writethrough on
15618         test_155_big_load
15619         restore_lustre_params < $p
15620         rm -f $p
15621 }
15622 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15623
15624 test_155h() {
15625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15626
15627         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15628
15629         save_writethrough $p
15630
15631         set_cache read off
15632         set_cache writethrough off
15633         test_155_big_load
15634         restore_lustre_params < $p
15635         rm -f $p
15636 }
15637 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15638
15639 test_156() {
15640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15641         remote_ost_nodsh && skip "remote OST with nodsh"
15642         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15643                 skip "stats not implemented on old servers"
15644         [ "$ost1_FSTYPE" = "zfs" ] &&
15645                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15646
15647         local CPAGES=3
15648         local BEFORE
15649         local AFTER
15650         local file="$DIR/$tfile"
15651         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15652
15653         save_writethrough $p
15654         roc_hit_init
15655
15656         log "Turn on read and write cache"
15657         set_cache read on
15658         set_cache writethrough on
15659
15660         log "Write data and read it back."
15661         log "Read should be satisfied from the cache."
15662         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15663         BEFORE=$(roc_hit)
15664         cancel_lru_locks osc
15665         cat $file >/dev/null
15666         AFTER=$(roc_hit)
15667         if ! let "AFTER - BEFORE == CPAGES"; then
15668                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15669         else
15670                 log "cache hits: before: $BEFORE, after: $AFTER"
15671         fi
15672
15673         log "Read again; it should be satisfied from the cache."
15674         BEFORE=$AFTER
15675         cancel_lru_locks osc
15676         cat $file >/dev/null
15677         AFTER=$(roc_hit)
15678         if ! let "AFTER - BEFORE == CPAGES"; then
15679                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15680         else
15681                 log "cache hits:: before: $BEFORE, after: $AFTER"
15682         fi
15683
15684         log "Turn off the read cache and turn on the write cache"
15685         set_cache read off
15686         set_cache writethrough on
15687
15688         log "Read again; it should be satisfied from the cache."
15689         BEFORE=$(roc_hit)
15690         cancel_lru_locks osc
15691         cat $file >/dev/null
15692         AFTER=$(roc_hit)
15693         if ! let "AFTER - BEFORE == CPAGES"; then
15694                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15695         else
15696                 log "cache hits:: before: $BEFORE, after: $AFTER"
15697         fi
15698
15699         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15700                 # > 2.12.56 uses pagecache if cached
15701                 log "Read again; it should not be satisfied from the cache."
15702                 BEFORE=$AFTER
15703                 cancel_lru_locks osc
15704                 cat $file >/dev/null
15705                 AFTER=$(roc_hit)
15706                 if ! let "AFTER - BEFORE == 0"; then
15707                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15708                 else
15709                         log "cache hits:: before: $BEFORE, after: $AFTER"
15710                 fi
15711         fi
15712
15713         log "Write data and read it back."
15714         log "Read should be satisfied from the cache."
15715         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15716         BEFORE=$(roc_hit)
15717         cancel_lru_locks osc
15718         cat $file >/dev/null
15719         AFTER=$(roc_hit)
15720         if ! let "AFTER - BEFORE == CPAGES"; then
15721                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15722         else
15723                 log "cache hits:: before: $BEFORE, after: $AFTER"
15724         fi
15725
15726         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15727                 # > 2.12.56 uses pagecache if cached
15728                 log "Read again; it should not be satisfied from the cache."
15729                 BEFORE=$AFTER
15730                 cancel_lru_locks osc
15731                 cat $file >/dev/null
15732                 AFTER=$(roc_hit)
15733                 if ! let "AFTER - BEFORE == 0"; then
15734                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15735                 else
15736                         log "cache hits:: before: $BEFORE, after: $AFTER"
15737                 fi
15738         fi
15739
15740         log "Turn off read and write cache"
15741         set_cache read off
15742         set_cache writethrough off
15743
15744         log "Write data and read it back"
15745         log "It should not be satisfied from the cache."
15746         rm -f $file
15747         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15748         cancel_lru_locks osc
15749         BEFORE=$(roc_hit)
15750         cat $file >/dev/null
15751         AFTER=$(roc_hit)
15752         if ! let "AFTER - BEFORE == 0"; then
15753                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15754         else
15755                 log "cache hits:: before: $BEFORE, after: $AFTER"
15756         fi
15757
15758         log "Turn on the read cache and turn off the write cache"
15759         set_cache read on
15760         set_cache writethrough off
15761
15762         log "Write data and read it back"
15763         log "It should not be satisfied from the cache."
15764         rm -f $file
15765         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15766         BEFORE=$(roc_hit)
15767         cancel_lru_locks osc
15768         cat $file >/dev/null
15769         AFTER=$(roc_hit)
15770         if ! let "AFTER - BEFORE == 0"; then
15771                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15772         else
15773                 log "cache hits:: before: $BEFORE, after: $AFTER"
15774         fi
15775
15776         log "Read again; it should be satisfied from the cache."
15777         BEFORE=$(roc_hit)
15778         cancel_lru_locks osc
15779         cat $file >/dev/null
15780         AFTER=$(roc_hit)
15781         if ! let "AFTER - BEFORE == CPAGES"; then
15782                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15783         else
15784                 log "cache hits:: before: $BEFORE, after: $AFTER"
15785         fi
15786
15787         restore_lustre_params < $p
15788         rm -f $p $file
15789 }
15790 run_test 156 "Verification of tunables"
15791
15792 test_160a() {
15793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15794         remote_mds_nodsh && skip "remote MDS with nodsh"
15795         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15796                 skip "Need MDS version at least 2.2.0"
15797
15798         changelog_register || error "changelog_register failed"
15799         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15800         changelog_users $SINGLEMDS | grep -q $cl_user ||
15801                 error "User $cl_user not found in changelog_users"
15802
15803         mkdir_on_mdt0 $DIR/$tdir
15804
15805         # change something
15806         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15807         changelog_clear 0 || error "changelog_clear failed"
15808         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15809         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15810         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15811         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15812         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15813         rm $DIR/$tdir/pics/desktop.jpg
15814
15815         echo "verifying changelog mask"
15816         changelog_chmask "-MKDIR"
15817         changelog_chmask "-CLOSE"
15818
15819         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15820         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15821
15822         changelog_chmask "+MKDIR"
15823         changelog_chmask "+CLOSE"
15824
15825         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15826         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15827
15828         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15829         CLOSES=$(changelog_dump | grep -c "CLOSE")
15830         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15831         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15832
15833         # verify contents
15834         echo "verifying target fid"
15835         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15836         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15837         [ "$fidc" == "$fidf" ] ||
15838                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15839         echo "verifying parent fid"
15840         # The FID returned from the Changelog may be the directory shard on
15841         # a different MDT, and not the FID returned by path2fid on the parent.
15842         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15843         # since this is what will matter when recreating this file in the tree.
15844         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15845         local pathp=$($LFS fid2path $MOUNT "$fidp")
15846         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15847                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15848
15849         echo "getting records for $cl_user"
15850         changelog_users $SINGLEMDS
15851         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15852         local nclr=3
15853         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15854                 error "changelog_clear failed"
15855         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15856         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15857         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15858                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15859
15860         local min0_rec=$(changelog_users $SINGLEMDS |
15861                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15862         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15863                           awk '{ print $1; exit; }')
15864
15865         changelog_dump | tail -n 5
15866         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15867         [ $first_rec == $((min0_rec + 1)) ] ||
15868                 error "first index should be $min0_rec + 1 not $first_rec"
15869
15870         # LU-3446 changelog index reset on MDT restart
15871         local cur_rec1=$(changelog_users $SINGLEMDS |
15872                          awk '/^current.index:/ { print $NF }')
15873         changelog_clear 0 ||
15874                 error "clear all changelog records for $cl_user failed"
15875         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15876         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15877                 error "Fail to start $SINGLEMDS"
15878         local cur_rec2=$(changelog_users $SINGLEMDS |
15879                          awk '/^current.index:/ { print $NF }')
15880         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15881         [ $cur_rec1 == $cur_rec2 ] ||
15882                 error "current index should be $cur_rec1 not $cur_rec2"
15883
15884         echo "verifying users from this test are deregistered"
15885         changelog_deregister || error "changelog_deregister failed"
15886         changelog_users $SINGLEMDS | grep -q $cl_user &&
15887                 error "User '$cl_user' still in changelog_users"
15888
15889         # lctl get_param -n mdd.*.changelog_users
15890         # current_index: 144
15891         # ID    index (idle seconds)
15892         # cl3   144   (2) mask=<list>
15893         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15894                 # this is the normal case where all users were deregistered
15895                 # make sure no new records are added when no users are present
15896                 local last_rec1=$(changelog_users $SINGLEMDS |
15897                                   awk '/^current.index:/ { print $NF }')
15898                 touch $DIR/$tdir/chloe
15899                 local last_rec2=$(changelog_users $SINGLEMDS |
15900                                   awk '/^current.index:/ { print $NF }')
15901                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15902                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15903         else
15904                 # any changelog users must be leftovers from a previous test
15905                 changelog_users $SINGLEMDS
15906                 echo "other changelog users; can't verify off"
15907         fi
15908 }
15909 run_test 160a "changelog sanity"
15910
15911 test_160b() { # LU-3587
15912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15913         remote_mds_nodsh && skip "remote MDS with nodsh"
15914         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15915                 skip "Need MDS version at least 2.2.0"
15916
15917         changelog_register || error "changelog_register failed"
15918         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15919         changelog_users $SINGLEMDS | grep -q $cl_user ||
15920                 error "User '$cl_user' not found in changelog_users"
15921
15922         local longname1=$(str_repeat a 255)
15923         local longname2=$(str_repeat b 255)
15924
15925         cd $DIR
15926         echo "creating very long named file"
15927         touch $longname1 || error "create of '$longname1' failed"
15928         echo "renaming very long named file"
15929         mv $longname1 $longname2
15930
15931         changelog_dump | grep RENME | tail -n 5
15932         rm -f $longname2
15933 }
15934 run_test 160b "Verify that very long rename doesn't crash in changelog"
15935
15936 test_160c() {
15937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15938         remote_mds_nodsh && skip "remote MDS with nodsh"
15939
15940         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15941                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15942                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15943                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15944
15945         local rc=0
15946
15947         # Registration step
15948         changelog_register || error "changelog_register failed"
15949
15950         rm -rf $DIR/$tdir
15951         mkdir -p $DIR/$tdir
15952         $MCREATE $DIR/$tdir/foo_160c
15953         changelog_chmask "-TRUNC"
15954         $TRUNCATE $DIR/$tdir/foo_160c 200
15955         changelog_chmask "+TRUNC"
15956         $TRUNCATE $DIR/$tdir/foo_160c 199
15957         changelog_dump | tail -n 5
15958         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15959         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15960 }
15961 run_test 160c "verify that changelog log catch the truncate event"
15962
15963 test_160d() {
15964         remote_mds_nodsh && skip "remote MDS with nodsh"
15965         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15967         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15968                 skip "Need MDS version at least 2.7.60"
15969
15970         # Registration step
15971         changelog_register || error "changelog_register failed"
15972
15973         mkdir -p $DIR/$tdir/migrate_dir
15974         changelog_clear 0 || error "changelog_clear failed"
15975
15976         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15977         changelog_dump | tail -n 5
15978         local migrates=$(changelog_dump | grep -c "MIGRT")
15979         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15980 }
15981 run_test 160d "verify that changelog log catch the migrate event"
15982
15983 test_160e() {
15984         remote_mds_nodsh && skip "remote MDS with nodsh"
15985
15986         # Create a user
15987         changelog_register || error "changelog_register failed"
15988
15989         local MDT0=$(facet_svc $SINGLEMDS)
15990         local rc
15991
15992         # No user (expect fail)
15993         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15994         rc=$?
15995         if [ $rc -eq 0 ]; then
15996                 error "Should fail without user"
15997         elif [ $rc -ne 4 ]; then
15998                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15999         fi
16000
16001         # Delete a future user (expect fail)
16002         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16003         rc=$?
16004         if [ $rc -eq 0 ]; then
16005                 error "Deleted non-existant user cl77"
16006         elif [ $rc -ne 2 ]; then
16007                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16008         fi
16009
16010         # Clear to a bad index (1 billion should be safe)
16011         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16012         rc=$?
16013
16014         if [ $rc -eq 0 ]; then
16015                 error "Successfully cleared to invalid CL index"
16016         elif [ $rc -ne 22 ]; then
16017                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16018         fi
16019 }
16020 run_test 160e "changelog negative testing (should return errors)"
16021
16022 test_160f() {
16023         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16024         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16025                 skip "Need MDS version at least 2.10.56"
16026
16027         local mdts=$(comma_list $(mdts_nodes))
16028
16029         # Create a user
16030         changelog_register || error "first changelog_register failed"
16031         changelog_register || error "second changelog_register failed"
16032         local cl_users
16033         declare -A cl_user1
16034         declare -A cl_user2
16035         local user_rec1
16036         local user_rec2
16037         local i
16038
16039         # generate some changelog records to accumulate on each MDT
16040         # use all_char because created files should be evenly distributed
16041         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16042                 error "test_mkdir $tdir failed"
16043         log "$(date +%s): creating first files"
16044         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16045                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16046                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16047         done
16048
16049         # check changelogs have been generated
16050         local start=$SECONDS
16051         local idle_time=$((MDSCOUNT * 5 + 5))
16052         local nbcl=$(changelog_dump | wc -l)
16053         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16054
16055         for param in "changelog_max_idle_time=$idle_time" \
16056                      "changelog_gc=1" \
16057                      "changelog_min_gc_interval=2" \
16058                      "changelog_min_free_cat_entries=3"; do
16059                 local MDT0=$(facet_svc $SINGLEMDS)
16060                 local var="${param%=*}"
16061                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16062
16063                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16064                 do_nodes $mdts $LCTL set_param mdd.*.$param
16065         done
16066
16067         # force cl_user2 to be idle (1st part), but also cancel the
16068         # cl_user1 records so that it is not evicted later in the test.
16069         local sleep1=$((idle_time / 2))
16070         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16071         sleep $sleep1
16072
16073         # simulate changelog catalog almost full
16074         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16075         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16076
16077         for i in $(seq $MDSCOUNT); do
16078                 cl_users=(${CL_USERS[mds$i]})
16079                 cl_user1[mds$i]="${cl_users[0]}"
16080                 cl_user2[mds$i]="${cl_users[1]}"
16081
16082                 [ -n "${cl_user1[mds$i]}" ] ||
16083                         error "mds$i: no user registered"
16084                 [ -n "${cl_user2[mds$i]}" ] ||
16085                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16086
16087                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16088                 [ -n "$user_rec1" ] ||
16089                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16090                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16091                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16092                 [ -n "$user_rec2" ] ||
16093                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16094                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16095                      "$user_rec1 + 2 == $user_rec2"
16096                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16097                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16098                               "$user_rec1 + 2, but is $user_rec2"
16099                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16100                 [ -n "$user_rec2" ] ||
16101                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16102                 [ $user_rec1 == $user_rec2 ] ||
16103                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16104                               "$user_rec1, but is $user_rec2"
16105         done
16106
16107         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16108         local sleep2=$((idle_time - (SECONDS - start) + 1))
16109         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16110         sleep $sleep2
16111
16112         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16113         # cl_user1 should be OK because it recently processed records.
16114         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16115         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16116                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16117                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16118         done
16119
16120         # ensure gc thread is done
16121         for i in $(mdts_nodes); do
16122                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16123                         error "$i: GC-thread not done"
16124         done
16125
16126         local first_rec
16127         for (( i = 1; i <= MDSCOUNT; i++ )); do
16128                 # check cl_user1 still registered
16129                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16130                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16131                 # check cl_user2 unregistered
16132                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16133                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16134
16135                 # check changelogs are present and starting at $user_rec1 + 1
16136                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16137                 [ -n "$user_rec1" ] ||
16138                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16139                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16140                             awk '{ print $1; exit; }')
16141
16142                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16143                 [ $((user_rec1 + 1)) == $first_rec ] ||
16144                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16145         done
16146 }
16147 run_test 160f "changelog garbage collect (timestamped users)"
16148
16149 test_160g() {
16150         remote_mds_nodsh && skip "remote MDS with nodsh"
16151         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16152                 skip "Need MDS version at least 2.14.55"
16153
16154         local mdts=$(comma_list $(mdts_nodes))
16155
16156         # Create a user
16157         changelog_register || error "first changelog_register failed"
16158         changelog_register || error "second changelog_register failed"
16159         local cl_users
16160         declare -A cl_user1
16161         declare -A cl_user2
16162         local user_rec1
16163         local user_rec2
16164         local i
16165
16166         # generate some changelog records to accumulate on each MDT
16167         # use all_char because created files should be evenly distributed
16168         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16169                 error "test_mkdir $tdir failed"
16170         for ((i = 0; i < MDSCOUNT; i++)); do
16171                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16172                         error "create $DIR/$tdir/d$i.1 failed"
16173         done
16174
16175         # check changelogs have been generated
16176         local nbcl=$(changelog_dump | wc -l)
16177         (( $nbcl > 0 )) || error "no changelogs found"
16178
16179         # reduce the max_idle_indexes value to make sure we exceed it
16180         for param in "changelog_max_idle_indexes=2" \
16181                      "changelog_gc=1" \
16182                      "changelog_min_gc_interval=2"; do
16183                 local MDT0=$(facet_svc $SINGLEMDS)
16184                 local var="${param%=*}"
16185                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16186
16187                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16188                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16189                         error "unable to set mdd.*.$param"
16190         done
16191
16192         local start=$SECONDS
16193         for i in $(seq $MDSCOUNT); do
16194                 cl_users=(${CL_USERS[mds$i]})
16195                 cl_user1[mds$i]="${cl_users[0]}"
16196                 cl_user2[mds$i]="${cl_users[1]}"
16197
16198                 [ -n "${cl_user1[mds$i]}" ] ||
16199                         error "mds$i: user1 is not registered"
16200                 [ -n "${cl_user2[mds$i]}" ] ||
16201                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16202
16203                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16204                 [ -n "$user_rec1" ] ||
16205                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16206                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16207                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16208                 [ -n "$user_rec2" ] ||
16209                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16210                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16211                      "$user_rec1 + 2 == $user_rec2"
16212                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16213                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16214                               "expected $user_rec1 + 2, but is $user_rec2"
16215                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16216                 [ -n "$user_rec2" ] ||
16217                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16218                 [ $user_rec1 == $user_rec2 ] ||
16219                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16220                               "expected $user_rec1, but is $user_rec2"
16221         done
16222
16223         # ensure we are past the previous changelog_min_gc_interval set above
16224         local sleep2=$((start + 2 - SECONDS))
16225         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16226         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16227         # cl_user1 should be OK because it recently processed records.
16228         for ((i = 0; i < MDSCOUNT; i++)); do
16229                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16230                         error "create $DIR/$tdir/d$i.3 failed"
16231         done
16232
16233         # ensure gc thread is done
16234         for i in $(mdts_nodes); do
16235                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16236                         error "$i: GC-thread not done"
16237         done
16238
16239         local first_rec
16240         for (( i = 1; i <= MDSCOUNT; i++ )); do
16241                 # check cl_user1 still registered
16242                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16243                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16244                 # check cl_user2 unregistered
16245                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16246                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16247
16248                 # check changelogs are present and starting at $user_rec1 + 1
16249                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16250                 [ -n "$user_rec1" ] ||
16251                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16252                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16253                             awk '{ print $1; exit; }')
16254
16255                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16256                 [ $((user_rec1 + 1)) == $first_rec ] ||
16257                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16258         done
16259 }
16260 run_test 160g "changelog garbage collect on idle records"
16261
16262 test_160h() {
16263         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16264         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16265                 skip "Need MDS version at least 2.10.56"
16266
16267         local mdts=$(comma_list $(mdts_nodes))
16268
16269         # Create a user
16270         changelog_register || error "first changelog_register failed"
16271         changelog_register || error "second changelog_register failed"
16272         local cl_users
16273         declare -A cl_user1
16274         declare -A cl_user2
16275         local user_rec1
16276         local user_rec2
16277         local i
16278
16279         # generate some changelog records to accumulate on each MDT
16280         # use all_char because created files should be evenly distributed
16281         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16282                 error "test_mkdir $tdir failed"
16283         for ((i = 0; i < MDSCOUNT; i++)); do
16284                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16285                         error "create $DIR/$tdir/d$i.1 failed"
16286         done
16287
16288         # check changelogs have been generated
16289         local nbcl=$(changelog_dump | wc -l)
16290         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16291
16292         for param in "changelog_max_idle_time=10" \
16293                      "changelog_gc=1" \
16294                      "changelog_min_gc_interval=2"; do
16295                 local MDT0=$(facet_svc $SINGLEMDS)
16296                 local var="${param%=*}"
16297                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16298
16299                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16300                 do_nodes $mdts $LCTL set_param mdd.*.$param
16301         done
16302
16303         # force cl_user2 to be idle (1st part)
16304         sleep 9
16305
16306         for i in $(seq $MDSCOUNT); do
16307                 cl_users=(${CL_USERS[mds$i]})
16308                 cl_user1[mds$i]="${cl_users[0]}"
16309                 cl_user2[mds$i]="${cl_users[1]}"
16310
16311                 [ -n "${cl_user1[mds$i]}" ] ||
16312                         error "mds$i: no user registered"
16313                 [ -n "${cl_user2[mds$i]}" ] ||
16314                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16315
16316                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16317                 [ -n "$user_rec1" ] ||
16318                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16319                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16320                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16321                 [ -n "$user_rec2" ] ||
16322                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16323                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16324                      "$user_rec1 + 2 == $user_rec2"
16325                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16326                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16327                               "$user_rec1 + 2, but is $user_rec2"
16328                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16329                 [ -n "$user_rec2" ] ||
16330                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16331                 [ $user_rec1 == $user_rec2 ] ||
16332                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16333                               "$user_rec1, but is $user_rec2"
16334         done
16335
16336         # force cl_user2 to be idle (2nd part) and to reach
16337         # changelog_max_idle_time
16338         sleep 2
16339
16340         # force each GC-thread start and block then
16341         # one per MDT/MDD, set fail_val accordingly
16342         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16343         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16344
16345         # generate more changelogs to trigger fail_loc
16346         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16347                 error "create $DIR/$tdir/${tfile}bis failed"
16348
16349         # stop MDT to stop GC-thread, should be done in back-ground as it will
16350         # block waiting for the thread to be released and exit
16351         declare -A stop_pids
16352         for i in $(seq $MDSCOUNT); do
16353                 stop mds$i &
16354                 stop_pids[mds$i]=$!
16355         done
16356
16357         for i in $(mdts_nodes); do
16358                 local facet
16359                 local nb=0
16360                 local facets=$(facets_up_on_host $i)
16361
16362                 for facet in ${facets//,/ }; do
16363                         if [[ $facet == mds* ]]; then
16364                                 nb=$((nb + 1))
16365                         fi
16366                 done
16367                 # ensure each MDS's gc threads are still present and all in "R"
16368                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16369                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16370                         error "$i: expected $nb GC-thread"
16371                 wait_update $i \
16372                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16373                         "R" 20 ||
16374                         error "$i: GC-thread not found in R-state"
16375                 # check umounts of each MDT on MDS have reached kthread_stop()
16376                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16377                         error "$i: expected $nb umount"
16378                 wait_update $i \
16379                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16380                         error "$i: umount not found in D-state"
16381         done
16382
16383         # release all GC-threads
16384         do_nodes $mdts $LCTL set_param fail_loc=0
16385
16386         # wait for MDT stop to complete
16387         for i in $(seq $MDSCOUNT); do
16388                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16389         done
16390
16391         # XXX
16392         # may try to check if any orphan changelog records are present
16393         # via ldiskfs/zfs and llog_reader...
16394
16395         # re-start/mount MDTs
16396         for i in $(seq $MDSCOUNT); do
16397                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16398                         error "Fail to start mds$i"
16399         done
16400
16401         local first_rec
16402         for i in $(seq $MDSCOUNT); do
16403                 # check cl_user1 still registered
16404                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16405                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16406                 # check cl_user2 unregistered
16407                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16408                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16409
16410                 # check changelogs are present and starting at $user_rec1 + 1
16411                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16412                 [ -n "$user_rec1" ] ||
16413                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16414                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16415                             awk '{ print $1; exit; }')
16416
16417                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16418                 [ $((user_rec1 + 1)) == $first_rec ] ||
16419                         error "mds$i: first index should be $user_rec1 + 1, " \
16420                               "but is $first_rec"
16421         done
16422 }
16423 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16424               "during mount"
16425
16426 test_160i() {
16427
16428         local mdts=$(comma_list $(mdts_nodes))
16429
16430         changelog_register || error "first changelog_register failed"
16431
16432         # generate some changelog records to accumulate on each MDT
16433         # use all_char because created files should be evenly distributed
16434         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16435                 error "test_mkdir $tdir failed"
16436         for ((i = 0; i < MDSCOUNT; i++)); do
16437                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16438                         error "create $DIR/$tdir/d$i.1 failed"
16439         done
16440
16441         # check changelogs have been generated
16442         local nbcl=$(changelog_dump | wc -l)
16443         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16444
16445         # simulate race between register and unregister
16446         # XXX as fail_loc is set per-MDS, with DNE configs the race
16447         # simulation will only occur for one MDT per MDS and for the
16448         # others the normal race scenario will take place
16449         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16450         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16451         do_nodes $mdts $LCTL set_param fail_val=1
16452
16453         # unregister 1st user
16454         changelog_deregister &
16455         local pid1=$!
16456         # wait some time for deregister work to reach race rdv
16457         sleep 2
16458         # register 2nd user
16459         changelog_register || error "2nd user register failed"
16460
16461         wait $pid1 || error "1st user deregister failed"
16462
16463         local i
16464         local last_rec
16465         declare -A LAST_REC
16466         for i in $(seq $MDSCOUNT); do
16467                 if changelog_users mds$i | grep "^cl"; then
16468                         # make sure new records are added with one user present
16469                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16470                                           awk '/^current.index:/ { print $NF }')
16471                 else
16472                         error "mds$i has no user registered"
16473                 fi
16474         done
16475
16476         # generate more changelog records to accumulate on each MDT
16477         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16478                 error "create $DIR/$tdir/${tfile}bis failed"
16479
16480         for i in $(seq $MDSCOUNT); do
16481                 last_rec=$(changelog_users $SINGLEMDS |
16482                            awk '/^current.index:/ { print $NF }')
16483                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16484                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16485                         error "changelogs are off on mds$i"
16486         done
16487 }
16488 run_test 160i "changelog user register/unregister race"
16489
16490 test_160j() {
16491         remote_mds_nodsh && skip "remote MDS with nodsh"
16492         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16493                 skip "Need MDS version at least 2.12.56"
16494
16495         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16496         stack_trap "umount $MOUNT2" EXIT
16497
16498         changelog_register || error "first changelog_register failed"
16499         stack_trap "changelog_deregister" EXIT
16500
16501         # generate some changelog
16502         # use all_char because created files should be evenly distributed
16503         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16504                 error "mkdir $tdir failed"
16505         for ((i = 0; i < MDSCOUNT; i++)); do
16506                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16507                         error "create $DIR/$tdir/d$i.1 failed"
16508         done
16509
16510         # open the changelog device
16511         exec 3>/dev/changelog-$FSNAME-MDT0000
16512         stack_trap "exec 3>&-" EXIT
16513         exec 4</dev/changelog-$FSNAME-MDT0000
16514         stack_trap "exec 4<&-" EXIT
16515
16516         # umount the first lustre mount
16517         umount $MOUNT
16518         stack_trap "mount_client $MOUNT" EXIT
16519
16520         # read changelog, which may or may not fail, but should not crash
16521         cat <&4 >/dev/null
16522
16523         # clear changelog
16524         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16525         changelog_users $SINGLEMDS | grep -q $cl_user ||
16526                 error "User $cl_user not found in changelog_users"
16527
16528         printf 'clear:'$cl_user':0' >&3
16529 }
16530 run_test 160j "client can be umounted while its chanangelog is being used"
16531
16532 test_160k() {
16533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16534         remote_mds_nodsh && skip "remote MDS with nodsh"
16535
16536         mkdir -p $DIR/$tdir/1/1
16537
16538         changelog_register || error "changelog_register failed"
16539         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16540
16541         changelog_users $SINGLEMDS | grep -q $cl_user ||
16542                 error "User '$cl_user' not found in changelog_users"
16543 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16544         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16545         rmdir $DIR/$tdir/1/1 & sleep 1
16546         mkdir $DIR/$tdir/2
16547         touch $DIR/$tdir/2/2
16548         rm -rf $DIR/$tdir/2
16549
16550         wait
16551         sleep 4
16552
16553         changelog_dump | grep rmdir || error "rmdir not recorded"
16554 }
16555 run_test 160k "Verify that changelog records are not lost"
16556
16557 # Verifies that a file passed as a parameter has recently had an operation
16558 # performed on it that has generated an MTIME changelog which contains the
16559 # correct parent FID. As files might reside on a different MDT from the
16560 # parent directory in DNE configurations, the FIDs are translated to paths
16561 # before being compared, which should be identical
16562 compare_mtime_changelog() {
16563         local file="${1}"
16564         local mdtidx
16565         local mtime
16566         local cl_fid
16567         local pdir
16568         local dir
16569
16570         mdtidx=$($LFS getstripe --mdt-index $file)
16571         mdtidx=$(printf "%04x" $mdtidx)
16572
16573         # Obtain the parent FID from the MTIME changelog
16574         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16575         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16576
16577         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16578         [ -z "$cl_fid" ] && error "parent FID not present"
16579
16580         # Verify that the path for the parent FID is the same as the path for
16581         # the test directory
16582         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16583
16584         dir=$(dirname $1)
16585
16586         [[ "${pdir%/}" == "$dir" ]] ||
16587                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16588 }
16589
16590 test_160l() {
16591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16592
16593         remote_mds_nodsh && skip "remote MDS with nodsh"
16594         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16595                 skip "Need MDS version at least 2.13.55"
16596
16597         local cl_user
16598
16599         changelog_register || error "changelog_register failed"
16600         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16601
16602         changelog_users $SINGLEMDS | grep -q $cl_user ||
16603                 error "User '$cl_user' not found in changelog_users"
16604
16605         # Clear some types so that MTIME changelogs are generated
16606         changelog_chmask "-CREAT"
16607         changelog_chmask "-CLOSE"
16608
16609         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16610
16611         # Test CL_MTIME during setattr
16612         touch $DIR/$tdir/$tfile
16613         compare_mtime_changelog $DIR/$tdir/$tfile
16614
16615         # Test CL_MTIME during close
16616         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16617         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16618 }
16619 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16620
16621 test_160m() {
16622         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16623         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16624                 skip "Need MDS version at least 2.14.51"
16625         local cl_users
16626         local cl_user1
16627         local cl_user2
16628         local pid1
16629
16630         # Create a user
16631         changelog_register || error "first changelog_register failed"
16632         changelog_register || error "second changelog_register failed"
16633
16634         cl_users=(${CL_USERS[mds1]})
16635         cl_user1="${cl_users[0]}"
16636         cl_user2="${cl_users[1]}"
16637         # generate some changelog records to accumulate on MDT0
16638         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16639         createmany -m $DIR/$tdir/$tfile 50 ||
16640                 error "create $DIR/$tdir/$tfile failed"
16641         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16642         rm -f $DIR/$tdir
16643
16644         # check changelogs have been generated
16645         local nbcl=$(changelog_dump | wc -l)
16646         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16647
16648 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16649         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16650
16651         __changelog_clear mds1 $cl_user1 +10
16652         __changelog_clear mds1 $cl_user2 0 &
16653         pid1=$!
16654         sleep 2
16655         __changelog_clear mds1 $cl_user1 0 ||
16656                 error "fail to cancel record for $cl_user1"
16657         wait $pid1
16658         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16659 }
16660 run_test 160m "Changelog clear race"
16661
16662 test_160n() {
16663         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16664         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16665                 skip "Need MDS version at least 2.14.51"
16666         local cl_users
16667         local cl_user1
16668         local cl_user2
16669         local pid1
16670         local first_rec
16671         local last_rec=0
16672
16673         # Create a user
16674         changelog_register || error "first changelog_register failed"
16675
16676         cl_users=(${CL_USERS[mds1]})
16677         cl_user1="${cl_users[0]}"
16678
16679         # generate some changelog records to accumulate on MDT0
16680         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16681         first_rec=$(changelog_users $SINGLEMDS |
16682                         awk '/^current.index:/ { print $NF }')
16683         while (( last_rec < (( first_rec + 65000)) )); do
16684                 createmany -m $DIR/$tdir/$tfile 10000 ||
16685                         error "create $DIR/$tdir/$tfile failed"
16686
16687                 for i in $(seq 0 10000); do
16688                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16689                                 > /dev/null
16690                 done
16691
16692                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16693                         error "unlinkmany failed unlink"
16694                 last_rec=$(changelog_users $SINGLEMDS |
16695                         awk '/^current.index:/ { print $NF }')
16696                 echo last record $last_rec
16697                 (( last_rec == 0 )) && error "no changelog found"
16698         done
16699
16700 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16701         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16702
16703         __changelog_clear mds1 $cl_user1 0 &
16704         pid1=$!
16705         sleep 2
16706         __changelog_clear mds1 $cl_user1 0 ||
16707                 error "fail to cancel record for $cl_user1"
16708         wait $pid1
16709         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16710 }
16711 run_test 160n "Changelog destroy race"
16712
16713 test_160o() {
16714         local mdt="$(facet_svc $SINGLEMDS)"
16715
16716         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16717         remote_mds_nodsh && skip "remote MDS with nodsh"
16718         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16719                 skip "Need MDS version at least 2.14.52"
16720
16721         changelog_register --user test_160o -m unlnk+close+open ||
16722                 error "changelog_register failed"
16723
16724         do_facet $SINGLEMDS $LCTL --device $mdt \
16725                                 changelog_register -u "Tt3_-#" &&
16726                 error "bad symbols in name should fail"
16727
16728         do_facet $SINGLEMDS $LCTL --device $mdt \
16729                                 changelog_register -u test_160o &&
16730                 error "the same name registration should fail"
16731
16732         do_facet $SINGLEMDS $LCTL --device $mdt \
16733                         changelog_register -u test_160toolongname &&
16734                 error "too long name registration should fail"
16735
16736         changelog_chmask "MARK+HSM"
16737         lctl get_param mdd.*.changelog*mask
16738         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16739         changelog_users $SINGLEMDS | grep -q $cl_user ||
16740                 error "User $cl_user not found in changelog_users"
16741         #verify username
16742         echo $cl_user | grep -q test_160o ||
16743                 error "User $cl_user has no specific name 'test160o'"
16744
16745         # change something
16746         changelog_clear 0 || error "changelog_clear failed"
16747         # generate some changelog records to accumulate on MDT0
16748         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16749         touch $DIR/$tdir/$tfile                 # open 1
16750
16751         OPENS=$(changelog_dump | grep -c "OPEN")
16752         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16753
16754         # must be no MKDIR it wasn't set as user mask
16755         MKDIR=$(changelog_dump | grep -c "MKDIR")
16756         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16757
16758         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16759                                 mdd.$mdt.changelog_current_mask -n)
16760         # register maskless user
16761         changelog_register || error "changelog_register failed"
16762         # effective mask should be not changed because it is not minimal
16763         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16764                                 mdd.$mdt.changelog_current_mask -n)
16765         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16766         # set server mask to minimal value
16767         changelog_chmask "MARK"
16768         # check effective mask again, should be treated as DEFMASK now
16769         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16770                                 mdd.$mdt.changelog_current_mask -n)
16771         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16772
16773         do_facet $SINGLEMDS $LCTL --device $mdt \
16774                                 changelog_deregister -u test_160o ||
16775                 error "cannot deregister by name"
16776 }
16777 run_test 160o "changelog user name and mask"
16778
16779 test_160p() {
16780         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16781         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16782                 skip "Need MDS version at least 2.14.51"
16783         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16784         local cl_users
16785         local cl_user1
16786         local entry_count
16787
16788         # Create a user
16789         changelog_register || error "first changelog_register failed"
16790
16791         cl_users=(${CL_USERS[mds1]})
16792         cl_user1="${cl_users[0]}"
16793
16794         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16795         createmany -m $DIR/$tdir/$tfile 50 ||
16796                 error "create $DIR/$tdir/$tfile failed"
16797         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16798         rm -rf $DIR/$tdir
16799
16800         # check changelogs have been generated
16801         entry_count=$(changelog_dump | wc -l)
16802         ((entry_count != 0)) || error "no changelog entries found"
16803
16804         # remove changelog_users and check that orphan entries are removed
16805         stop mds1
16806         local dev=$(mdsdevname 1)
16807         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
16808         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
16809         entry_count=$(changelog_dump | wc -l)
16810         ((entry_count == 0)) ||
16811                 error "found $entry_count changelog entries, expected none"
16812 }
16813 run_test 160p "Changelog orphan cleanup with no users"
16814
16815 test_160q() {
16816         local mdt="$(facet_svc $SINGLEMDS)"
16817         local clu
16818
16819         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16820         remote_mds_nodsh && skip "remote MDS with nodsh"
16821         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16822                 skip "Need MDS version at least 2.14.54"
16823
16824         # set server mask to minimal value like server init does
16825         changelog_chmask "MARK"
16826         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16827                 error "changelog_register failed"
16828         # check effective mask again, should be treated as DEFMASK now
16829         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16830                                 mdd.$mdt.changelog_current_mask -n)
16831         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16832                 error "changelog_deregister failed"
16833         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16834 }
16835 run_test 160q "changelog effective mask is DEFMASK if not set"
16836
16837 test_160s() {
16838         remote_mds_nodsh && skip "remote MDS with nodsh"
16839         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16840                 skip "Need MDS version at least 2.14.55"
16841
16842         local mdts=$(comma_list $(mdts_nodes))
16843
16844         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16845         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16846                                        fail_val=$((24 * 3600 * 10))
16847
16848         # Create a user which is 10 days old
16849         changelog_register || error "first changelog_register failed"
16850         local cl_users
16851         declare -A cl_user1
16852         local i
16853
16854         # generate some changelog records to accumulate on each MDT
16855         # use all_char because created files should be evenly distributed
16856         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16857                 error "test_mkdir $tdir failed"
16858         for ((i = 0; i < MDSCOUNT; i++)); do
16859                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16860                         error "create $DIR/$tdir/d$i.1 failed"
16861         done
16862
16863         # check changelogs have been generated
16864         local nbcl=$(changelog_dump | wc -l)
16865         (( nbcl > 0 )) || error "no changelogs found"
16866
16867         # reduce the max_idle_indexes value to make sure we exceed it
16868         for param in "changelog_max_idle_indexes=2097446912" \
16869                      "changelog_max_idle_time=2592000" \
16870                      "changelog_gc=1" \
16871                      "changelog_min_gc_interval=2"; do
16872                 local MDT0=$(facet_svc $SINGLEMDS)
16873                 local var="${param%=*}"
16874                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16875
16876                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16877                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16878                         error "unable to set mdd.*.$param"
16879         done
16880
16881         local start=$SECONDS
16882         for i in $(seq $MDSCOUNT); do
16883                 cl_users=(${CL_USERS[mds$i]})
16884                 cl_user1[mds$i]="${cl_users[0]}"
16885
16886                 [[ -n "${cl_user1[mds$i]}" ]] ||
16887                         error "mds$i: no user registered"
16888         done
16889
16890         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16891         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16892
16893         # ensure we are past the previous changelog_min_gc_interval set above
16894         local sleep2=$((start + 2 - SECONDS))
16895         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16896
16897         # Generate one more changelog to trigger GC
16898         for ((i = 0; i < MDSCOUNT; i++)); do
16899                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16900                         error "create $DIR/$tdir/d$i.3 failed"
16901         done
16902
16903         # ensure gc thread is done
16904         for node in $(mdts_nodes); do
16905                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16906                         error "$node: GC-thread not done"
16907         done
16908
16909         do_nodes $mdts $LCTL set_param fail_loc=0
16910
16911         for (( i = 1; i <= MDSCOUNT; i++ )); do
16912                 # check cl_user1 is purged
16913                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16914                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16915         done
16916         return 0
16917 }
16918 run_test 160s "changelog garbage collect on idle records * time"
16919
16920 test_161a() {
16921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16922
16923         test_mkdir -c1 $DIR/$tdir
16924         cp /etc/hosts $DIR/$tdir/$tfile
16925         test_mkdir -c1 $DIR/$tdir/foo1
16926         test_mkdir -c1 $DIR/$tdir/foo2
16927         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16928         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16929         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16930         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16931         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16932         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16933                 $LFS fid2path $DIR $FID
16934                 error "bad link ea"
16935         fi
16936         # middle
16937         rm $DIR/$tdir/foo2/zachary
16938         # last
16939         rm $DIR/$tdir/foo2/thor
16940         # first
16941         rm $DIR/$tdir/$tfile
16942         # rename
16943         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16944         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16945                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16946         rm $DIR/$tdir/foo2/maggie
16947
16948         # overflow the EA
16949         local longname=$tfile.avg_len_is_thirty_two_
16950         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16951                 error_noexit 'failed to unlink many hardlinks'" EXIT
16952         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16953                 error "failed to hardlink many files"
16954         links=$($LFS fid2path $DIR $FID | wc -l)
16955         echo -n "${links}/1000 links in link EA"
16956         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16957 }
16958 run_test 161a "link ea sanity"
16959
16960 test_161b() {
16961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16962         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16963
16964         local MDTIDX=1
16965         local remote_dir=$DIR/$tdir/remote_dir
16966
16967         mkdir -p $DIR/$tdir
16968         $LFS mkdir -i $MDTIDX $remote_dir ||
16969                 error "create remote directory failed"
16970
16971         cp /etc/hosts $remote_dir/$tfile
16972         mkdir -p $remote_dir/foo1
16973         mkdir -p $remote_dir/foo2
16974         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16975         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16976         ln $remote_dir/$tfile $remote_dir/foo1/luna
16977         ln $remote_dir/$tfile $remote_dir/foo2/thor
16978
16979         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16980                      tr -d ']')
16981         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16982                 $LFS fid2path $DIR $FID
16983                 error "bad link ea"
16984         fi
16985         # middle
16986         rm $remote_dir/foo2/zachary
16987         # last
16988         rm $remote_dir/foo2/thor
16989         # first
16990         rm $remote_dir/$tfile
16991         # rename
16992         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16993         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16994         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16995                 $LFS fid2path $DIR $FID
16996                 error "bad link rename"
16997         fi
16998         rm $remote_dir/foo2/maggie
16999
17000         # overflow the EA
17001         local longname=filename_avg_len_is_thirty_two_
17002         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17003                 error "failed to hardlink many files"
17004         links=$($LFS fid2path $DIR $FID | wc -l)
17005         echo -n "${links}/1000 links in link EA"
17006         [[ ${links} -gt 60 ]] ||
17007                 error "expected at least 60 links in link EA"
17008         unlinkmany $remote_dir/foo2/$longname 1000 ||
17009         error "failed to unlink many hardlinks"
17010 }
17011 run_test 161b "link ea sanity under remote directory"
17012
17013 test_161c() {
17014         remote_mds_nodsh && skip "remote MDS with nodsh"
17015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17016         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17017                 skip "Need MDS version at least 2.1.5"
17018
17019         # define CLF_RENAME_LAST 0x0001
17020         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17021         changelog_register || error "changelog_register failed"
17022
17023         rm -rf $DIR/$tdir
17024         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17025         touch $DIR/$tdir/foo_161c
17026         touch $DIR/$tdir/bar_161c
17027         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17028         changelog_dump | grep RENME | tail -n 5
17029         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17030         changelog_clear 0 || error "changelog_clear failed"
17031         if [ x$flags != "x0x1" ]; then
17032                 error "flag $flags is not 0x1"
17033         fi
17034
17035         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17036         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17037         touch $DIR/$tdir/foo_161c
17038         touch $DIR/$tdir/bar_161c
17039         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17040         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17041         changelog_dump | grep RENME | tail -n 5
17042         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17043         changelog_clear 0 || error "changelog_clear failed"
17044         if [ x$flags != "x0x0" ]; then
17045                 error "flag $flags is not 0x0"
17046         fi
17047         echo "rename overwrite a target having nlink > 1," \
17048                 "changelog record has flags of $flags"
17049
17050         # rename doesn't overwrite a target (changelog flag 0x0)
17051         touch $DIR/$tdir/foo_161c
17052         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17053         changelog_dump | grep RENME | tail -n 5
17054         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17055         changelog_clear 0 || error "changelog_clear failed"
17056         if [ x$flags != "x0x0" ]; then
17057                 error "flag $flags is not 0x0"
17058         fi
17059         echo "rename doesn't overwrite a target," \
17060                 "changelog record has flags of $flags"
17061
17062         # define CLF_UNLINK_LAST 0x0001
17063         # unlink a file having nlink = 1 (changelog flag 0x1)
17064         rm -f $DIR/$tdir/foo2_161c
17065         changelog_dump | grep UNLNK | tail -n 5
17066         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17067         changelog_clear 0 || error "changelog_clear failed"
17068         if [ x$flags != "x0x1" ]; then
17069                 error "flag $flags is not 0x1"
17070         fi
17071         echo "unlink a file having nlink = 1," \
17072                 "changelog record has flags of $flags"
17073
17074         # unlink a file having nlink > 1 (changelog flag 0x0)
17075         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17076         rm -f $DIR/$tdir/foobar_161c
17077         changelog_dump | grep UNLNK | tail -n 5
17078         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17079         changelog_clear 0 || error "changelog_clear failed"
17080         if [ x$flags != "x0x0" ]; then
17081                 error "flag $flags is not 0x0"
17082         fi
17083         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17084 }
17085 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17086
17087 test_161d() {
17088         remote_mds_nodsh && skip "remote MDS with nodsh"
17089         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17090
17091         local pid
17092         local fid
17093
17094         changelog_register || error "changelog_register failed"
17095
17096         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17097         # interfer with $MOUNT/.lustre/fid/ access
17098         mkdir $DIR/$tdir
17099         [[ $? -eq 0 ]] || error "mkdir failed"
17100
17101         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17102         $LCTL set_param fail_loc=0x8000140c
17103         # 5s pause
17104         $LCTL set_param fail_val=5
17105
17106         # create file
17107         echo foofoo > $DIR/$tdir/$tfile &
17108         pid=$!
17109
17110         # wait for create to be delayed
17111         sleep 2
17112
17113         ps -p $pid
17114         [[ $? -eq 0 ]] || error "create should be blocked"
17115
17116         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17117         stack_trap "rm -f $tempfile"
17118         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17119         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17120         # some delay may occur during ChangeLog publishing and file read just
17121         # above, that could allow file write to happen finally
17122         [[ -s $tempfile ]] && echo "file should be empty"
17123
17124         $LCTL set_param fail_loc=0
17125
17126         wait $pid
17127         [[ $? -eq 0 ]] || error "create failed"
17128 }
17129 run_test 161d "create with concurrent .lustre/fid access"
17130
17131 check_path() {
17132         local expected="$1"
17133         shift
17134         local fid="$2"
17135
17136         local path
17137         path=$($LFS fid2path "$@")
17138         local rc=$?
17139
17140         if [ $rc -ne 0 ]; then
17141                 error "path looked up of '$expected' failed: rc=$rc"
17142         elif [ "$path" != "$expected" ]; then
17143                 error "path looked up '$path' instead of '$expected'"
17144         else
17145                 echo "FID '$fid' resolves to path '$path' as expected"
17146         fi
17147 }
17148
17149 test_162a() { # was test_162
17150         test_mkdir -p -c1 $DIR/$tdir/d2
17151         touch $DIR/$tdir/d2/$tfile
17152         touch $DIR/$tdir/d2/x1
17153         touch $DIR/$tdir/d2/x2
17154         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17155         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17156         # regular file
17157         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17158         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17159
17160         # softlink
17161         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17162         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17163         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17164
17165         # softlink to wrong file
17166         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17167         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17168         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17169
17170         # hardlink
17171         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17172         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17173         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17174         # fid2path dir/fsname should both work
17175         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17176         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17177
17178         # hardlink count: check that there are 2 links
17179         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17180         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17181
17182         # hardlink indexing: remove the first link
17183         rm $DIR/$tdir/d2/p/q/r/hlink
17184         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17185 }
17186 run_test 162a "path lookup sanity"
17187
17188 test_162b() {
17189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17190         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17191
17192         mkdir $DIR/$tdir
17193         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17194                                 error "create striped dir failed"
17195
17196         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17197                                         tail -n 1 | awk '{print $2}')
17198         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17199
17200         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17201         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17202
17203         # regular file
17204         for ((i=0;i<5;i++)); do
17205                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17206                         error "get fid for f$i failed"
17207                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17208
17209                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17210                         error "get fid for d$i failed"
17211                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17212         done
17213
17214         return 0
17215 }
17216 run_test 162b "striped directory path lookup sanity"
17217
17218 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17219 test_162c() {
17220         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17221                 skip "Need MDS version at least 2.7.51"
17222
17223         local lpath=$tdir.local
17224         local rpath=$tdir.remote
17225
17226         test_mkdir $DIR/$lpath
17227         test_mkdir $DIR/$rpath
17228
17229         for ((i = 0; i <= 101; i++)); do
17230                 lpath="$lpath/$i"
17231                 mkdir $DIR/$lpath
17232                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17233                         error "get fid for local directory $DIR/$lpath failed"
17234                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17235
17236                 rpath="$rpath/$i"
17237                 test_mkdir $DIR/$rpath
17238                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17239                         error "get fid for remote directory $DIR/$rpath failed"
17240                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17241         done
17242
17243         return 0
17244 }
17245 run_test 162c "fid2path works with paths 100 or more directories deep"
17246
17247 oalr_event_count() {
17248         local event="${1}"
17249         local trace="${2}"
17250
17251         awk -v name="${FSNAME}-OST0000" \
17252             -v event="${event}" \
17253             '$1 == "TRACE" && $2 == event && $3 == name' \
17254             "${trace}" |
17255         wc -l
17256 }
17257
17258 oalr_expect_event_count() {
17259         local event="${1}"
17260         local trace="${2}"
17261         local expect="${3}"
17262         local count
17263
17264         count=$(oalr_event_count "${event}" "${trace}")
17265         if ((count == expect)); then
17266                 return 0
17267         fi
17268
17269         error_noexit "${event} event count was '${count}', expected ${expect}"
17270         cat "${trace}" >&2
17271         exit 1
17272 }
17273
17274 cleanup_165() {
17275         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17276         stop ost1
17277         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17278 }
17279
17280 setup_165() {
17281         sync # Flush previous IOs so we can count log entries.
17282         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17283         stack_trap cleanup_165 EXIT
17284 }
17285
17286 test_165a() {
17287         local trace="/tmp/${tfile}.trace"
17288         local rc
17289         local count
17290
17291         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17292                 skip "OFD access log unsupported"
17293
17294         setup_165
17295         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17296         sleep 5
17297
17298         do_facet ost1 ofd_access_log_reader --list
17299         stop ost1
17300
17301         do_facet ost1 killall -TERM ofd_access_log_reader
17302         wait
17303         rc=$?
17304
17305         if ((rc != 0)); then
17306                 error "ofd_access_log_reader exited with rc = '${rc}'"
17307         fi
17308
17309         # Parse trace file for discovery events:
17310         oalr_expect_event_count alr_log_add "${trace}" 1
17311         oalr_expect_event_count alr_log_eof "${trace}" 1
17312         oalr_expect_event_count alr_log_free "${trace}" 1
17313 }
17314 run_test 165a "ofd access log discovery"
17315
17316 test_165b() {
17317         local trace="/tmp/${tfile}.trace"
17318         local file="${DIR}/${tfile}"
17319         local pfid1
17320         local pfid2
17321         local -a entry
17322         local rc
17323         local count
17324         local size
17325         local flags
17326
17327         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17328                 skip "OFD access log unsupported"
17329
17330         setup_165
17331         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17332         sleep 5
17333
17334         do_facet ost1 ofd_access_log_reader --list
17335
17336         lfs setstripe -c 1 -i 0 "${file}"
17337         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17338                 error "cannot create '${file}'"
17339
17340         sleep 5
17341         do_facet ost1 killall -TERM ofd_access_log_reader
17342         wait
17343         rc=$?
17344
17345         if ((rc != 0)); then
17346                 error "ofd_access_log_reader exited with rc = '${rc}'"
17347         fi
17348
17349         oalr_expect_event_count alr_log_entry "${trace}" 1
17350
17351         pfid1=$($LFS path2fid "${file}")
17352
17353         # 1     2             3   4    5     6   7    8    9     10
17354         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17355         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17356
17357         echo "entry = '${entry[*]}'" >&2
17358
17359         pfid2=${entry[4]}
17360         if [[ "${pfid1}" != "${pfid2}" ]]; then
17361                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17362         fi
17363
17364         size=${entry[8]}
17365         if ((size != 1048576)); then
17366                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17367         fi
17368
17369         flags=${entry[10]}
17370         if [[ "${flags}" != "w" ]]; then
17371                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17372         fi
17373
17374         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17375         sleep 5
17376
17377         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17378                 error "cannot read '${file}'"
17379         sleep 5
17380
17381         do_facet ost1 killall -TERM ofd_access_log_reader
17382         wait
17383         rc=$?
17384
17385         if ((rc != 0)); then
17386                 error "ofd_access_log_reader exited with rc = '${rc}'"
17387         fi
17388
17389         oalr_expect_event_count alr_log_entry "${trace}" 1
17390
17391         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17392         echo "entry = '${entry[*]}'" >&2
17393
17394         pfid2=${entry[4]}
17395         if [[ "${pfid1}" != "${pfid2}" ]]; then
17396                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17397         fi
17398
17399         size=${entry[8]}
17400         if ((size != 524288)); then
17401                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17402         fi
17403
17404         flags=${entry[10]}
17405         if [[ "${flags}" != "r" ]]; then
17406                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17407         fi
17408 }
17409 run_test 165b "ofd access log entries are produced and consumed"
17410
17411 test_165c() {
17412         local trace="/tmp/${tfile}.trace"
17413         local file="${DIR}/${tdir}/${tfile}"
17414
17415         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17416                 skip "OFD access log unsupported"
17417
17418         test_mkdir "${DIR}/${tdir}"
17419
17420         setup_165
17421         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17422         sleep 5
17423
17424         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17425
17426         # 4096 / 64 = 64. Create twice as many entries.
17427         for ((i = 0; i < 128; i++)); do
17428                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17429                         error "cannot create file"
17430         done
17431
17432         sync
17433
17434         do_facet ost1 killall -TERM ofd_access_log_reader
17435         wait
17436         rc=$?
17437         if ((rc != 0)); then
17438                 error "ofd_access_log_reader exited with rc = '${rc}'"
17439         fi
17440
17441         unlinkmany  "${file}-%d" 128
17442 }
17443 run_test 165c "full ofd access logs do not block IOs"
17444
17445 oal_get_read_count() {
17446         local stats="$1"
17447
17448         # STATS lustre-OST0001 alr_read_count 1
17449
17450         do_facet ost1 cat "${stats}" |
17451         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17452              END { print count; }'
17453 }
17454
17455 oal_expect_read_count() {
17456         local stats="$1"
17457         local count
17458         local expect="$2"
17459
17460         # Ask ofd_access_log_reader to write stats.
17461         do_facet ost1 killall -USR1 ofd_access_log_reader
17462
17463         # Allow some time for things to happen.
17464         sleep 1
17465
17466         count=$(oal_get_read_count "${stats}")
17467         if ((count == expect)); then
17468                 return 0
17469         fi
17470
17471         error_noexit "bad read count, got ${count}, expected ${expect}"
17472         do_facet ost1 cat "${stats}" >&2
17473         exit 1
17474 }
17475
17476 test_165d() {
17477         local stats="/tmp/${tfile}.stats"
17478         local file="${DIR}/${tdir}/${tfile}"
17479         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17480
17481         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17482                 skip "OFD access log unsupported"
17483
17484         test_mkdir "${DIR}/${tdir}"
17485
17486         setup_165
17487         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17488         sleep 5
17489
17490         lfs setstripe -c 1 -i 0 "${file}"
17491
17492         do_facet ost1 lctl set_param "${param}=rw"
17493         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17494                 error "cannot create '${file}'"
17495         oal_expect_read_count "${stats}" 1
17496
17497         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17498                 error "cannot read '${file}'"
17499         oal_expect_read_count "${stats}" 2
17500
17501         do_facet ost1 lctl set_param "${param}=r"
17502         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17503                 error "cannot create '${file}'"
17504         oal_expect_read_count "${stats}" 2
17505
17506         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17507                 error "cannot read '${file}'"
17508         oal_expect_read_count "${stats}" 3
17509
17510         do_facet ost1 lctl set_param "${param}=w"
17511         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17512                 error "cannot create '${file}'"
17513         oal_expect_read_count "${stats}" 4
17514
17515         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17516                 error "cannot read '${file}'"
17517         oal_expect_read_count "${stats}" 4
17518
17519         do_facet ost1 lctl set_param "${param}=0"
17520         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17521                 error "cannot create '${file}'"
17522         oal_expect_read_count "${stats}" 4
17523
17524         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17525                 error "cannot read '${file}'"
17526         oal_expect_read_count "${stats}" 4
17527
17528         do_facet ost1 killall -TERM ofd_access_log_reader
17529         wait
17530         rc=$?
17531         if ((rc != 0)); then
17532                 error "ofd_access_log_reader exited with rc = '${rc}'"
17533         fi
17534 }
17535 run_test 165d "ofd_access_log mask works"
17536
17537 test_165e() {
17538         local stats="/tmp/${tfile}.stats"
17539         local file0="${DIR}/${tdir}-0/${tfile}"
17540         local file1="${DIR}/${tdir}-1/${tfile}"
17541
17542         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17543                 skip "OFD access log unsupported"
17544
17545         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17546
17547         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17548         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17549
17550         lfs setstripe -c 1 -i 0 "${file0}"
17551         lfs setstripe -c 1 -i 0 "${file1}"
17552
17553         setup_165
17554         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17555         sleep 5
17556
17557         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17558                 error "cannot create '${file0}'"
17559         sync
17560         oal_expect_read_count "${stats}" 0
17561
17562         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17563                 error "cannot create '${file1}'"
17564         sync
17565         oal_expect_read_count "${stats}" 1
17566
17567         do_facet ost1 killall -TERM ofd_access_log_reader
17568         wait
17569         rc=$?
17570         if ((rc != 0)); then
17571                 error "ofd_access_log_reader exited with rc = '${rc}'"
17572         fi
17573 }
17574 run_test 165e "ofd_access_log MDT index filter works"
17575
17576 test_165f() {
17577         local trace="/tmp/${tfile}.trace"
17578         local rc
17579         local count
17580
17581         setup_165
17582         do_facet ost1 timeout 60 ofd_access_log_reader \
17583                 --exit-on-close --debug=- --trace=- > "${trace}" &
17584         sleep 5
17585         stop ost1
17586
17587         wait
17588         rc=$?
17589
17590         if ((rc != 0)); then
17591                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17592                 cat "${trace}"
17593                 exit 1
17594         fi
17595 }
17596 run_test 165f "ofd_access_log_reader --exit-on-close works"
17597
17598 test_169() {
17599         # do directio so as not to populate the page cache
17600         log "creating a 10 Mb file"
17601         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17602                 error "multiop failed while creating a file"
17603         log "starting reads"
17604         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17605         log "truncating the file"
17606         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17607                 error "multiop failed while truncating the file"
17608         log "killing dd"
17609         kill %+ || true # reads might have finished
17610         echo "wait until dd is finished"
17611         wait
17612         log "removing the temporary file"
17613         rm -rf $DIR/$tfile || error "tmp file removal failed"
17614 }
17615 run_test 169 "parallel read and truncate should not deadlock"
17616
17617 test_170() {
17618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17619
17620         $LCTL clear     # bug 18514
17621         $LCTL debug_daemon start $TMP/${tfile}_log_good
17622         touch $DIR/$tfile
17623         $LCTL debug_daemon stop
17624         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17625                 error "sed failed to read log_good"
17626
17627         $LCTL debug_daemon start $TMP/${tfile}_log_good
17628         rm -rf $DIR/$tfile
17629         $LCTL debug_daemon stop
17630
17631         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17632                error "lctl df log_bad failed"
17633
17634         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17635         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17636
17637         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17638         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17639
17640         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17641                 error "bad_line good_line1 good_line2 are empty"
17642
17643         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17644         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17645         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17646
17647         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17648         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17649         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17650
17651         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17652                 error "bad_line_new good_line_new are empty"
17653
17654         local expected_good=$((good_line1 + good_line2*2))
17655
17656         rm -f $TMP/${tfile}*
17657         # LU-231, short malformed line may not be counted into bad lines
17658         if [ $bad_line -ne $bad_line_new ] &&
17659                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17660                 error "expected $bad_line bad lines, but got $bad_line_new"
17661                 return 1
17662         fi
17663
17664         if [ $expected_good -ne $good_line_new ]; then
17665                 error "expected $expected_good good lines, but got $good_line_new"
17666                 return 2
17667         fi
17668         true
17669 }
17670 run_test 170 "test lctl df to handle corrupted log ====================="
17671
17672 test_171() { # bug20592
17673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17674
17675         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17676         $LCTL set_param fail_loc=0x50e
17677         $LCTL set_param fail_val=3000
17678         multiop_bg_pause $DIR/$tfile O_s || true
17679         local MULTIPID=$!
17680         kill -USR1 $MULTIPID
17681         # cause log dump
17682         sleep 3
17683         wait $MULTIPID
17684         if dmesg | grep "recursive fault"; then
17685                 error "caught a recursive fault"
17686         fi
17687         $LCTL set_param fail_loc=0
17688         true
17689 }
17690 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17691
17692 # it would be good to share it with obdfilter-survey/iokit-libecho code
17693 setup_obdecho_osc () {
17694         local rc=0
17695         local ost_nid=$1
17696         local obdfilter_name=$2
17697         echo "Creating new osc for $obdfilter_name on $ost_nid"
17698         # make sure we can find loopback nid
17699         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17700
17701         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17702                            ${obdfilter_name}_osc_UUID || rc=2; }
17703         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17704                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17705         return $rc
17706 }
17707
17708 cleanup_obdecho_osc () {
17709         local obdfilter_name=$1
17710         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17711         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17712         return 0
17713 }
17714
17715 obdecho_test() {
17716         local OBD=$1
17717         local node=$2
17718         local pages=${3:-64}
17719         local rc=0
17720         local id
17721
17722         local count=10
17723         local obd_size=$(get_obd_size $node $OBD)
17724         local page_size=$(get_page_size $node)
17725         if [[ -n "$obd_size" ]]; then
17726                 local new_count=$((obd_size / (pages * page_size / 1024)))
17727                 [[ $new_count -ge $count ]] || count=$new_count
17728         fi
17729
17730         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17731         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17732                            rc=2; }
17733         if [ $rc -eq 0 ]; then
17734             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17735             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17736         fi
17737         echo "New object id is $id"
17738         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17739                            rc=4; }
17740         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17741                            "test_brw $count w v $pages $id" || rc=4; }
17742         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17743                            rc=4; }
17744         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17745                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17746         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17747                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17748         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17749         return $rc
17750 }
17751
17752 test_180a() {
17753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17754
17755         if ! [ -d /sys/fs/lustre/echo_client ] &&
17756            ! module_loaded obdecho; then
17757                 load_module obdecho/obdecho &&
17758                         stack_trap "rmmod obdecho" EXIT ||
17759                         error "unable to load obdecho on client"
17760         fi
17761
17762         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17763         local host=$($LCTL get_param -n osc.$osc.import |
17764                      awk '/current_connection:/ { print $2 }' )
17765         local target=$($LCTL get_param -n osc.$osc.import |
17766                        awk '/target:/ { print $2 }' )
17767         target=${target%_UUID}
17768
17769         if [ -n "$target" ]; then
17770                 setup_obdecho_osc $host $target &&
17771                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17772                         { error "obdecho setup failed with $?"; return; }
17773
17774                 obdecho_test ${target}_osc client ||
17775                         error "obdecho_test failed on ${target}_osc"
17776         else
17777                 $LCTL get_param osc.$osc.import
17778                 error "there is no osc.$osc.import target"
17779         fi
17780 }
17781 run_test 180a "test obdecho on osc"
17782
17783 test_180b() {
17784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17785         remote_ost_nodsh && skip "remote OST with nodsh"
17786
17787         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17788                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17789                 error "failed to load module obdecho"
17790
17791         local target=$(do_facet ost1 $LCTL dl |
17792                        awk '/obdfilter/ { print $4; exit; }')
17793
17794         if [ -n "$target" ]; then
17795                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17796         else
17797                 do_facet ost1 $LCTL dl
17798                 error "there is no obdfilter target on ost1"
17799         fi
17800 }
17801 run_test 180b "test obdecho directly on obdfilter"
17802
17803 test_180c() { # LU-2598
17804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17805         remote_ost_nodsh && skip "remote OST with nodsh"
17806         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17807                 skip "Need MDS version at least 2.4.0"
17808
17809         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17810                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17811                 error "failed to load module obdecho"
17812
17813         local target=$(do_facet ost1 $LCTL dl |
17814                        awk '/obdfilter/ { print $4; exit; }')
17815
17816         if [ -n "$target" ]; then
17817                 local pages=16384 # 64MB bulk I/O RPC size
17818
17819                 obdecho_test "$target" ost1 "$pages" ||
17820                         error "obdecho_test with pages=$pages failed with $?"
17821         else
17822                 do_facet ost1 $LCTL dl
17823                 error "there is no obdfilter target on ost1"
17824         fi
17825 }
17826 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17827
17828 test_181() { # bug 22177
17829         test_mkdir $DIR/$tdir
17830         # create enough files to index the directory
17831         createmany -o $DIR/$tdir/foobar 4000
17832         # print attributes for debug purpose
17833         lsattr -d .
17834         # open dir
17835         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17836         MULTIPID=$!
17837         # remove the files & current working dir
17838         unlinkmany $DIR/$tdir/foobar 4000
17839         rmdir $DIR/$tdir
17840         kill -USR1 $MULTIPID
17841         wait $MULTIPID
17842         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17843         return 0
17844 }
17845 run_test 181 "Test open-unlinked dir ========================"
17846
17847 test_182a() {
17848         local fcount=1000
17849         local tcount=10
17850
17851         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17852
17853         $LCTL set_param mdc.*.rpc_stats=clear
17854
17855         for (( i = 0; i < $tcount; i++ )) ; do
17856                 mkdir $DIR/$tdir/$i
17857         done
17858
17859         for (( i = 0; i < $tcount; i++ )) ; do
17860                 createmany -o $DIR/$tdir/$i/f- $fcount &
17861         done
17862         wait
17863
17864         for (( i = 0; i < $tcount; i++ )) ; do
17865                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17866         done
17867         wait
17868
17869         $LCTL get_param mdc.*.rpc_stats
17870
17871         rm -rf $DIR/$tdir
17872 }
17873 run_test 182a "Test parallel modify metadata operations from mdc"
17874
17875 test_182b() {
17876         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17877         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
17878         local dcount=1000
17879         local tcount=10
17880         local stime
17881         local etime
17882         local delta
17883
17884         do_facet mds1 $LCTL list_param \
17885                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
17886                 skip "MDS lacks parallel RPC handling"
17887
17888         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17889
17890         rpc_count=$(do_facet mds1 $LCTL get_param -n \
17891                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
17892
17893         stime=$(date +%s)
17894         createmany -i 0 -d $DIR/$tdir/t- $tcount
17895
17896         for (( i = 0; i < $tcount; i++ )) ; do
17897                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17898         done
17899         wait
17900         etime=$(date +%s)
17901         delta=$((etime - stime))
17902         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
17903
17904         stime=$(date +%s)
17905         for (( i = 0; i < $tcount; i++ )) ; do
17906                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
17907         done
17908         wait
17909         etime=$(date +%s)
17910         delta=$((etime - stime))
17911         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
17912
17913         rm -rf $DIR/$tdir
17914
17915         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17916
17917         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
17918
17919         stime=$(date +%s)
17920         createmany -i 0 -d $DIR/$tdir/t- $tcount
17921
17922         for (( i = 0; i < $tcount; i++ )) ; do
17923                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
17924         done
17925         wait
17926         etime=$(date +%s)
17927         delta=$((etime - stime))
17928         echo "Time for file creation $delta sec for 1 RPC sent at a time"
17929
17930         stime=$(date +%s)
17931         for (( i = 0; i < $tcount; i++ )) ; do
17932                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
17933         done
17934         wait
17935         etime=$(date +%s)
17936         delta=$((etime - stime))
17937         echo "Time for file removal $delta sec for 1 RPC sent at a time"
17938
17939         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
17940 }
17941 run_test 182b "Test parallel modify metadata operations from osp"
17942
17943 test_183() { # LU-2275
17944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17945         remote_mds_nodsh && skip "remote MDS with nodsh"
17946         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17947                 skip "Need MDS version at least 2.3.56"
17948
17949         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17950         echo aaa > $DIR/$tdir/$tfile
17951
17952 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17953         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17954
17955         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17956         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17957
17958         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17959
17960         # Flush negative dentry cache
17961         touch $DIR/$tdir/$tfile
17962
17963         # We are not checking for any leaked references here, they'll
17964         # become evident next time we do cleanup with module unload.
17965         rm -rf $DIR/$tdir
17966 }
17967 run_test 183 "No crash or request leak in case of strange dispositions ========"
17968
17969 # test suite 184 is for LU-2016, LU-2017
17970 test_184a() {
17971         check_swap_layouts_support
17972
17973         dir0=$DIR/$tdir/$testnum
17974         test_mkdir -p -c1 $dir0
17975         ref1=/etc/passwd
17976         ref2=/etc/group
17977         file1=$dir0/f1
17978         file2=$dir0/f2
17979         $LFS setstripe -c1 $file1
17980         cp $ref1 $file1
17981         $LFS setstripe -c2 $file2
17982         cp $ref2 $file2
17983         gen1=$($LFS getstripe -g $file1)
17984         gen2=$($LFS getstripe -g $file2)
17985
17986         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17987         gen=$($LFS getstripe -g $file1)
17988         [[ $gen1 != $gen ]] ||
17989                 error "Layout generation on $file1 does not change"
17990         gen=$($LFS getstripe -g $file2)
17991         [[ $gen2 != $gen ]] ||
17992                 error "Layout generation on $file2 does not change"
17993
17994         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17995         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17996
17997         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17998 }
17999 run_test 184a "Basic layout swap"
18000
18001 test_184b() {
18002         check_swap_layouts_support
18003
18004         dir0=$DIR/$tdir/$testnum
18005         mkdir -p $dir0 || error "creating dir $dir0"
18006         file1=$dir0/f1
18007         file2=$dir0/f2
18008         file3=$dir0/f3
18009         dir1=$dir0/d1
18010         dir2=$dir0/d2
18011         mkdir $dir1 $dir2
18012         $LFS setstripe -c1 $file1
18013         $LFS setstripe -c2 $file2
18014         $LFS setstripe -c1 $file3
18015         chown $RUNAS_ID $file3
18016         gen1=$($LFS getstripe -g $file1)
18017         gen2=$($LFS getstripe -g $file2)
18018
18019         $LFS swap_layouts $dir1 $dir2 &&
18020                 error "swap of directories layouts should fail"
18021         $LFS swap_layouts $dir1 $file1 &&
18022                 error "swap of directory and file layouts should fail"
18023         $RUNAS $LFS swap_layouts $file1 $file2 &&
18024                 error "swap of file we cannot write should fail"
18025         $LFS swap_layouts $file1 $file3 &&
18026                 error "swap of file with different owner should fail"
18027         /bin/true # to clear error code
18028 }
18029 run_test 184b "Forbidden layout swap (will generate errors)"
18030
18031 test_184c() {
18032         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18033         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18034         check_swap_layouts_support
18035         check_swap_layout_no_dom $DIR
18036
18037         local dir0=$DIR/$tdir/$testnum
18038         mkdir -p $dir0 || error "creating dir $dir0"
18039
18040         local ref1=$dir0/ref1
18041         local ref2=$dir0/ref2
18042         local file1=$dir0/file1
18043         local file2=$dir0/file2
18044         # create a file large enough for the concurrent test
18045         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18046         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18047         echo "ref file size: ref1($(stat -c %s $ref1))," \
18048              "ref2($(stat -c %s $ref2))"
18049
18050         cp $ref2 $file2
18051         dd if=$ref1 of=$file1 bs=16k &
18052         local DD_PID=$!
18053
18054         # Make sure dd starts to copy file, but wait at most 5 seconds
18055         local loops=0
18056         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18057
18058         $LFS swap_layouts $file1 $file2
18059         local rc=$?
18060         wait $DD_PID
18061         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18062         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18063
18064         # how many bytes copied before swapping layout
18065         local copied=$(stat -c %s $file2)
18066         local remaining=$(stat -c %s $ref1)
18067         remaining=$((remaining - copied))
18068         echo "Copied $copied bytes before swapping layout..."
18069
18070         cmp -n $copied $file1 $ref2 | grep differ &&
18071                 error "Content mismatch [0, $copied) of ref2 and file1"
18072         cmp -n $copied $file2 $ref1 ||
18073                 error "Content mismatch [0, $copied) of ref1 and file2"
18074         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18075                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18076
18077         # clean up
18078         rm -f $ref1 $ref2 $file1 $file2
18079 }
18080 run_test 184c "Concurrent write and layout swap"
18081
18082 test_184d() {
18083         check_swap_layouts_support
18084         check_swap_layout_no_dom $DIR
18085         [ -z "$(which getfattr 2>/dev/null)" ] &&
18086                 skip_env "no getfattr command"
18087
18088         local file1=$DIR/$tdir/$tfile-1
18089         local file2=$DIR/$tdir/$tfile-2
18090         local file3=$DIR/$tdir/$tfile-3
18091         local lovea1
18092         local lovea2
18093
18094         mkdir -p $DIR/$tdir
18095         touch $file1 || error "create $file1 failed"
18096         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18097                 error "create $file2 failed"
18098         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18099                 error "create $file3 failed"
18100         lovea1=$(get_layout_param $file1)
18101
18102         $LFS swap_layouts $file2 $file3 ||
18103                 error "swap $file2 $file3 layouts failed"
18104         $LFS swap_layouts $file1 $file2 ||
18105                 error "swap $file1 $file2 layouts failed"
18106
18107         lovea2=$(get_layout_param $file2)
18108         echo "$lovea1"
18109         echo "$lovea2"
18110         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18111
18112         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18113         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18114 }
18115 run_test 184d "allow stripeless layouts swap"
18116
18117 test_184e() {
18118         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18119                 skip "Need MDS version at least 2.6.94"
18120         check_swap_layouts_support
18121         check_swap_layout_no_dom $DIR
18122         [ -z "$(which getfattr 2>/dev/null)" ] &&
18123                 skip_env "no getfattr command"
18124
18125         local file1=$DIR/$tdir/$tfile-1
18126         local file2=$DIR/$tdir/$tfile-2
18127         local file3=$DIR/$tdir/$tfile-3
18128         local lovea
18129
18130         mkdir -p $DIR/$tdir
18131         touch $file1 || error "create $file1 failed"
18132         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18133                 error "create $file2 failed"
18134         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18135                 error "create $file3 failed"
18136
18137         $LFS swap_layouts $file1 $file2 ||
18138                 error "swap $file1 $file2 layouts failed"
18139
18140         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18141         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18142
18143         echo 123 > $file1 || error "Should be able to write into $file1"
18144
18145         $LFS swap_layouts $file1 $file3 ||
18146                 error "swap $file1 $file3 layouts failed"
18147
18148         echo 123 > $file1 || error "Should be able to write into $file1"
18149
18150         rm -rf $file1 $file2 $file3
18151 }
18152 run_test 184e "Recreate layout after stripeless layout swaps"
18153
18154 test_184f() {
18155         # Create a file with name longer than sizeof(struct stat) ==
18156         # 144 to see if we can get chars from the file name to appear
18157         # in the returned striping. Note that 'f' == 0x66.
18158         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18159
18160         mkdir -p $DIR/$tdir
18161         mcreate $DIR/$tdir/$file
18162         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18163                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18164         fi
18165 }
18166 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18167
18168 test_185() { # LU-2441
18169         # LU-3553 - no volatile file support in old servers
18170         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18171                 skip "Need MDS version at least 2.3.60"
18172
18173         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18174         touch $DIR/$tdir/spoo
18175         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18176         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18177                 error "cannot create/write a volatile file"
18178         [ "$FILESET" == "" ] &&
18179         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18180                 error "FID is still valid after close"
18181
18182         multiop_bg_pause $DIR/$tdir vVw4096_c
18183         local multi_pid=$!
18184
18185         local OLD_IFS=$IFS
18186         IFS=":"
18187         local fidv=($fid)
18188         IFS=$OLD_IFS
18189         # assume that the next FID for this client is sequential, since stdout
18190         # is unfortunately eaten by multiop_bg_pause
18191         local n=$((${fidv[1]} + 1))
18192         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18193         if [ "$FILESET" == "" ]; then
18194                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18195                         error "FID is missing before close"
18196         fi
18197         kill -USR1 $multi_pid
18198         # 1 second delay, so if mtime change we will see it
18199         sleep 1
18200         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18201         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18202 }
18203 run_test 185 "Volatile file support"
18204
18205 function create_check_volatile() {
18206         local idx=$1
18207         local tgt
18208
18209         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18210         local PID=$!
18211         sleep 1
18212         local FID=$(cat /tmp/${tfile}.fid)
18213         [ "$FID" == "" ] && error "can't get FID for volatile"
18214         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18215         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18216         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18217         kill -USR1 $PID
18218         wait
18219         sleep 1
18220         cancel_lru_locks mdc # flush opencache
18221         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18222         return 0
18223 }
18224
18225 test_185a(){
18226         # LU-12516 - volatile creation via .lustre
18227         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18228                 skip "Need MDS version at least 2.3.55"
18229
18230         create_check_volatile 0
18231         [ $MDSCOUNT -lt 2 ] && return 0
18232
18233         # DNE case
18234         create_check_volatile 1
18235
18236         return 0
18237 }
18238 run_test 185a "Volatile file creation in .lustre/fid/"
18239
18240 test_187a() {
18241         remote_mds_nodsh && skip "remote MDS with nodsh"
18242         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18243                 skip "Need MDS version at least 2.3.0"
18244
18245         local dir0=$DIR/$tdir/$testnum
18246         mkdir -p $dir0 || error "creating dir $dir0"
18247
18248         local file=$dir0/file1
18249         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18250         local dv1=$($LFS data_version $file)
18251         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18252         local dv2=$($LFS data_version $file)
18253         [[ $dv1 != $dv2 ]] ||
18254                 error "data version did not change on write $dv1 == $dv2"
18255
18256         # clean up
18257         rm -f $file1
18258 }
18259 run_test 187a "Test data version change"
18260
18261 test_187b() {
18262         remote_mds_nodsh && skip "remote MDS with nodsh"
18263         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18264                 skip "Need MDS version at least 2.3.0"
18265
18266         local dir0=$DIR/$tdir/$testnum
18267         mkdir -p $dir0 || error "creating dir $dir0"
18268
18269         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18270         [[ ${DV[0]} != ${DV[1]} ]] ||
18271                 error "data version did not change on write"\
18272                       " ${DV[0]} == ${DV[1]}"
18273
18274         # clean up
18275         rm -f $file1
18276 }
18277 run_test 187b "Test data version change on volatile file"
18278
18279 test_200() {
18280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18281         remote_mgs_nodsh && skip "remote MGS with nodsh"
18282         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18283
18284         local POOL=${POOL:-cea1}
18285         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18286         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18287         # Pool OST targets
18288         local first_ost=0
18289         local last_ost=$(($OSTCOUNT - 1))
18290         local ost_step=2
18291         local ost_list=$(seq $first_ost $ost_step $last_ost)
18292         local ost_range="$first_ost $last_ost $ost_step"
18293         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18294         local file_dir=$POOL_ROOT/file_tst
18295         local subdir=$test_path/subdir
18296         local rc=0
18297
18298         while : ; do
18299                 # former test_200a test_200b
18300                 pool_add $POOL                          || { rc=$? ; break; }
18301                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18302                 # former test_200c test_200d
18303                 mkdir -p $test_path
18304                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18305                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18306                 mkdir -p $subdir
18307                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18308                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18309                                                         || { rc=$? ; break; }
18310                 # former test_200e test_200f
18311                 local files=$((OSTCOUNT*3))
18312                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18313                                                         || { rc=$? ; break; }
18314                 pool_create_files $POOL $file_dir $files "$ost_list" \
18315                                                         || { rc=$? ; break; }
18316                 # former test_200g test_200h
18317                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18318                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18319
18320                 # former test_201a test_201b test_201c
18321                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18322
18323                 local f=$test_path/$tfile
18324                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18325                 pool_remove $POOL $f                    || { rc=$? ; break; }
18326                 break
18327         done
18328
18329         destroy_test_pools
18330
18331         return $rc
18332 }
18333 run_test 200 "OST pools"
18334
18335 # usage: default_attr <count | size | offset>
18336 default_attr() {
18337         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18338 }
18339
18340 # usage: check_default_stripe_attr
18341 check_default_stripe_attr() {
18342         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18343         case $1 in
18344         --stripe-count|-c)
18345                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18346         --stripe-size|-S)
18347                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18348         --stripe-index|-i)
18349                 EXPECTED=-1;;
18350         *)
18351                 error "unknown getstripe attr '$1'"
18352         esac
18353
18354         [ $ACTUAL == $EXPECTED ] ||
18355                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18356 }
18357
18358 test_204a() {
18359         test_mkdir $DIR/$tdir
18360         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18361
18362         check_default_stripe_attr --stripe-count
18363         check_default_stripe_attr --stripe-size
18364         check_default_stripe_attr --stripe-index
18365 }
18366 run_test 204a "Print default stripe attributes"
18367
18368 test_204b() {
18369         test_mkdir $DIR/$tdir
18370         $LFS setstripe --stripe-count 1 $DIR/$tdir
18371
18372         check_default_stripe_attr --stripe-size
18373         check_default_stripe_attr --stripe-index
18374 }
18375 run_test 204b "Print default stripe size and offset"
18376
18377 test_204c() {
18378         test_mkdir $DIR/$tdir
18379         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18380
18381         check_default_stripe_attr --stripe-count
18382         check_default_stripe_attr --stripe-index
18383 }
18384 run_test 204c "Print default stripe count and offset"
18385
18386 test_204d() {
18387         test_mkdir $DIR/$tdir
18388         $LFS setstripe --stripe-index 0 $DIR/$tdir
18389
18390         check_default_stripe_attr --stripe-count
18391         check_default_stripe_attr --stripe-size
18392 }
18393 run_test 204d "Print default stripe count and size"
18394
18395 test_204e() {
18396         test_mkdir $DIR/$tdir
18397         $LFS setstripe -d $DIR/$tdir
18398
18399         check_default_stripe_attr --stripe-count --raw
18400         check_default_stripe_attr --stripe-size --raw
18401         check_default_stripe_attr --stripe-index --raw
18402 }
18403 run_test 204e "Print raw stripe attributes"
18404
18405 test_204f() {
18406         test_mkdir $DIR/$tdir
18407         $LFS setstripe --stripe-count 1 $DIR/$tdir
18408
18409         check_default_stripe_attr --stripe-size --raw
18410         check_default_stripe_attr --stripe-index --raw
18411 }
18412 run_test 204f "Print raw stripe size and offset"
18413
18414 test_204g() {
18415         test_mkdir $DIR/$tdir
18416         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18417
18418         check_default_stripe_attr --stripe-count --raw
18419         check_default_stripe_attr --stripe-index --raw
18420 }
18421 run_test 204g "Print raw stripe count and offset"
18422
18423 test_204h() {
18424         test_mkdir $DIR/$tdir
18425         $LFS setstripe --stripe-index 0 $DIR/$tdir
18426
18427         check_default_stripe_attr --stripe-count --raw
18428         check_default_stripe_attr --stripe-size --raw
18429 }
18430 run_test 204h "Print raw stripe count and size"
18431
18432 # Figure out which job scheduler is being used, if any,
18433 # or use a fake one
18434 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18435         JOBENV=SLURM_JOB_ID
18436 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18437         JOBENV=LSB_JOBID
18438 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18439         JOBENV=PBS_JOBID
18440 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18441         JOBENV=LOADL_STEP_ID
18442 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18443         JOBENV=JOB_ID
18444 else
18445         $LCTL list_param jobid_name > /dev/null 2>&1
18446         if [ $? -eq 0 ]; then
18447                 JOBENV=nodelocal
18448         else
18449                 JOBENV=FAKE_JOBID
18450         fi
18451 fi
18452 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18453
18454 verify_jobstats() {
18455         local cmd=($1)
18456         shift
18457         local facets="$@"
18458
18459 # we don't really need to clear the stats for this test to work, since each
18460 # command has a unique jobid, but it makes debugging easier if needed.
18461 #       for facet in $facets; do
18462 #               local dev=$(convert_facet2label $facet)
18463 #               # clear old jobstats
18464 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18465 #       done
18466
18467         # use a new JobID for each test, or we might see an old one
18468         [ "$JOBENV" = "FAKE_JOBID" ] &&
18469                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18470
18471         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18472
18473         [ "$JOBENV" = "nodelocal" ] && {
18474                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18475                 $LCTL set_param jobid_name=$FAKE_JOBID
18476                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18477         }
18478
18479         log "Test: ${cmd[*]}"
18480         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18481
18482         if [ $JOBENV = "FAKE_JOBID" ]; then
18483                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18484         else
18485                 ${cmd[*]}
18486         fi
18487
18488         # all files are created on OST0000
18489         for facet in $facets; do
18490                 local stats="*.$(convert_facet2label $facet).job_stats"
18491
18492                 # strip out libtool wrappers for in-tree executables
18493                 if (( $(do_facet $facet lctl get_param $stats |
18494                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18495                         do_facet $facet lctl get_param $stats
18496                         error "No jobstats for $JOBVAL found on $facet::$stats"
18497                 fi
18498         done
18499 }
18500
18501 jobstats_set() {
18502         local new_jobenv=$1
18503
18504         set_persistent_param_and_check client "jobid_var" \
18505                 "$FSNAME.sys.jobid_var" $new_jobenv
18506 }
18507
18508 test_205a() { # Job stats
18509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18510         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18511                 skip "Need MDS version with at least 2.7.1"
18512         remote_mgs_nodsh && skip "remote MGS with nodsh"
18513         remote_mds_nodsh && skip "remote MDS with nodsh"
18514         remote_ost_nodsh && skip "remote OST with nodsh"
18515         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18516                 skip "Server doesn't support jobstats"
18517         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18518
18519         local old_jobenv=$($LCTL get_param -n jobid_var)
18520         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18521
18522         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18523                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18524         else
18525                 stack_trap "do_facet mgs $PERM_CMD \
18526                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18527         fi
18528         changelog_register
18529
18530         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18531                                 mdt.*.job_cleanup_interval | head -n 1)
18532         local new_interval=5
18533         do_facet $SINGLEMDS \
18534                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18535         stack_trap "do_facet $SINGLEMDS \
18536                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18537         local start=$SECONDS
18538
18539         local cmd
18540         # mkdir
18541         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18542         verify_jobstats "$cmd" "$SINGLEMDS"
18543         # rmdir
18544         cmd="rmdir $DIR/$tdir"
18545         verify_jobstats "$cmd" "$SINGLEMDS"
18546         # mkdir on secondary MDT
18547         if [ $MDSCOUNT -gt 1 ]; then
18548                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18549                 verify_jobstats "$cmd" "mds2"
18550         fi
18551         # mknod
18552         cmd="mknod $DIR/$tfile c 1 3"
18553         verify_jobstats "$cmd" "$SINGLEMDS"
18554         # unlink
18555         cmd="rm -f $DIR/$tfile"
18556         verify_jobstats "$cmd" "$SINGLEMDS"
18557         # create all files on OST0000 so verify_jobstats can find OST stats
18558         # open & close
18559         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18560         verify_jobstats "$cmd" "$SINGLEMDS"
18561         # setattr
18562         cmd="touch $DIR/$tfile"
18563         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18564         # write
18565         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18566         verify_jobstats "$cmd" "ost1"
18567         # read
18568         cancel_lru_locks osc
18569         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18570         verify_jobstats "$cmd" "ost1"
18571         # truncate
18572         cmd="$TRUNCATE $DIR/$tfile 0"
18573         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18574         # rename
18575         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18576         verify_jobstats "$cmd" "$SINGLEMDS"
18577         # jobstats expiry - sleep until old stats should be expired
18578         local left=$((new_interval + 5 - (SECONDS - start)))
18579         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18580                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18581                         "0" $left
18582         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18583         verify_jobstats "$cmd" "$SINGLEMDS"
18584         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18585             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18586
18587         # Ensure that jobid are present in changelog (if supported by MDS)
18588         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18589                 changelog_dump | tail -10
18590                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18591                 [ $jobids -eq 9 ] ||
18592                         error "Wrong changelog jobid count $jobids != 9"
18593
18594                 # LU-5862
18595                 JOBENV="disable"
18596                 jobstats_set $JOBENV
18597                 touch $DIR/$tfile
18598                 changelog_dump | grep $tfile
18599                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18600                 [ $jobids -eq 0 ] ||
18601                         error "Unexpected jobids when jobid_var=$JOBENV"
18602         fi
18603
18604         # test '%j' access to environment variable - if supported
18605         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18606                 JOBENV="JOBCOMPLEX"
18607                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18608
18609                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18610         fi
18611
18612         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18613                 JOBENV="JOBCOMPLEX"
18614                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18615
18616                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18617         fi
18618
18619         # test '%j' access to per-session jobid - if supported
18620         if lctl list_param jobid_this_session > /dev/null 2>&1
18621         then
18622                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18623                 lctl set_param jobid_this_session=$USER
18624
18625                 JOBENV="JOBCOMPLEX"
18626                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18627
18628                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18629         fi
18630 }
18631 run_test 205a "Verify job stats"
18632
18633 # LU-13117, LU-13597
18634 test_205b() {
18635         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18636                 skip "Need MDS version at least 2.13.54.91"
18637
18638         job_stats="mdt.*.job_stats"
18639         $LCTL set_param $job_stats=clear
18640         # Setting jobid_var to USER might not be supported
18641         $LCTL set_param jobid_var=USER || true
18642         $LCTL set_param jobid_name="%e.%u"
18643         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18644         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18645                 grep "job_id:.*foolish" &&
18646                         error "Unexpected jobid found"
18647         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18648                 grep "open:.*min.*max.*sum" ||
18649                         error "wrong job_stats format found"
18650 }
18651 run_test 205b "Verify job stats jobid and output format"
18652
18653 # LU-13733
18654 test_205c() {
18655         $LCTL set_param llite.*.stats=0
18656         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18657         $LCTL get_param llite.*.stats
18658         $LCTL get_param llite.*.stats | grep \
18659                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18660                         error "wrong client stats format found"
18661 }
18662 run_test 205c "Verify client stats format"
18663
18664 # LU-1480, LU-1773 and LU-1657
18665 test_206() {
18666         mkdir -p $DIR/$tdir
18667         $LFS setstripe -c -1 $DIR/$tdir
18668 #define OBD_FAIL_LOV_INIT 0x1403
18669         $LCTL set_param fail_loc=0xa0001403
18670         $LCTL set_param fail_val=1
18671         touch $DIR/$tdir/$tfile || true
18672 }
18673 run_test 206 "fail lov_init_raid0() doesn't lbug"
18674
18675 test_207a() {
18676         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18677         local fsz=`stat -c %s $DIR/$tfile`
18678         cancel_lru_locks mdc
18679
18680         # do not return layout in getattr intent
18681 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18682         $LCTL set_param fail_loc=0x170
18683         local sz=`stat -c %s $DIR/$tfile`
18684
18685         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18686
18687         rm -rf $DIR/$tfile
18688 }
18689 run_test 207a "can refresh layout at glimpse"
18690
18691 test_207b() {
18692         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18693         local cksum=`md5sum $DIR/$tfile`
18694         local fsz=`stat -c %s $DIR/$tfile`
18695         cancel_lru_locks mdc
18696         cancel_lru_locks osc
18697
18698         # do not return layout in getattr intent
18699 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18700         $LCTL set_param fail_loc=0x171
18701
18702         # it will refresh layout after the file is opened but before read issues
18703         echo checksum is "$cksum"
18704         echo "$cksum" |md5sum -c --quiet || error "file differs"
18705
18706         rm -rf $DIR/$tfile
18707 }
18708 run_test 207b "can refresh layout at open"
18709
18710 test_208() {
18711         # FIXME: in this test suite, only RD lease is used. This is okay
18712         # for now as only exclusive open is supported. After generic lease
18713         # is done, this test suite should be revised. - Jinshan
18714
18715         remote_mds_nodsh && skip "remote MDS with nodsh"
18716         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18717                 skip "Need MDS version at least 2.4.52"
18718
18719         echo "==== test 1: verify get lease work"
18720         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18721
18722         echo "==== test 2: verify lease can be broken by upcoming open"
18723         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18724         local PID=$!
18725         sleep 2
18726
18727         $MULTIOP $DIR/$tfile oO_RDWR:c
18728         kill -USR1 $PID && wait $PID || error "break lease error"
18729
18730         echo "==== test 3: verify lease can't be granted if an open already exists"
18731         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18732         local PID=$!
18733         sleep 2
18734
18735         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18736         kill -USR1 $PID && wait $PID || error "open file error"
18737
18738         echo "==== test 4: lease can sustain over recovery"
18739         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18740         PID=$!
18741         sleep 2
18742
18743         fail mds1
18744
18745         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18746
18747         echo "==== test 5: lease broken can't be regained by replay"
18748         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18749         PID=$!
18750         sleep 2
18751
18752         # open file to break lease and then recovery
18753         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18754         fail mds1
18755
18756         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18757
18758         rm -f $DIR/$tfile
18759 }
18760 run_test 208 "Exclusive open"
18761
18762 test_209() {
18763         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18764                 skip_env "must have disp_stripe"
18765
18766         touch $DIR/$tfile
18767         sync; sleep 5; sync;
18768
18769         echo 3 > /proc/sys/vm/drop_caches
18770         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18771                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18772         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18773
18774         # open/close 500 times
18775         for i in $(seq 500); do
18776                 cat $DIR/$tfile
18777         done
18778
18779         echo 3 > /proc/sys/vm/drop_caches
18780         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18781                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18782         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18783
18784         echo "before: $req_before, after: $req_after"
18785         [ $((req_after - req_before)) -ge 300 ] &&
18786                 error "open/close requests are not freed"
18787         return 0
18788 }
18789 run_test 209 "read-only open/close requests should be freed promptly"
18790
18791 test_210() {
18792         local pid
18793
18794         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18795         pid=$!
18796         sleep 1
18797
18798         $LFS getstripe $DIR/$tfile
18799         kill -USR1 $pid
18800         wait $pid || error "multiop failed"
18801
18802         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18803         pid=$!
18804         sleep 1
18805
18806         $LFS getstripe $DIR/$tfile
18807         kill -USR1 $pid
18808         wait $pid || error "multiop failed"
18809 }
18810 run_test 210 "lfs getstripe does not break leases"
18811
18812 test_212() {
18813         size=`date +%s`
18814         size=$((size % 8192 + 1))
18815         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18816         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18817         rm -f $DIR/f212 $DIR/f212.xyz
18818 }
18819 run_test 212 "Sendfile test ============================================"
18820
18821 test_213() {
18822         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18823         cancel_lru_locks osc
18824         lctl set_param fail_loc=0x8000040f
18825         # generate a read lock
18826         cat $DIR/$tfile > /dev/null
18827         # write to the file, it will try to cancel the above read lock.
18828         cat /etc/hosts >> $DIR/$tfile
18829 }
18830 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18831
18832 test_214() { # for bug 20133
18833         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18834         for (( i=0; i < 340; i++ )) ; do
18835                 touch $DIR/$tdir/d214c/a$i
18836         done
18837
18838         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18839         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18840         ls $DIR/d214c || error "ls $DIR/d214c failed"
18841         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18842         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18843 }
18844 run_test 214 "hash-indexed directory test - bug 20133"
18845
18846 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18847 create_lnet_proc_files() {
18848         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18849 }
18850
18851 # counterpart of create_lnet_proc_files
18852 remove_lnet_proc_files() {
18853         rm -f $TMP/lnet_$1.sys
18854 }
18855
18856 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18857 # 3rd arg as regexp for body
18858 check_lnet_proc_stats() {
18859         local l=$(cat "$TMP/lnet_$1" |wc -l)
18860         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18861
18862         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18863 }
18864
18865 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18866 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18867 # optional and can be regexp for 2nd line (lnet.routes case)
18868 check_lnet_proc_entry() {
18869         local blp=2          # blp stands for 'position of 1st line of body'
18870         [ -z "$5" ] || blp=3 # lnet.routes case
18871
18872         local l=$(cat "$TMP/lnet_$1" |wc -l)
18873         # subtracting one from $blp because the body can be empty
18874         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18875
18876         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18877                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18878
18879         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18880                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18881
18882         # bail out if any unexpected line happened
18883         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18884         [ "$?" != 0 ] || error "$2 misformatted"
18885 }
18886
18887 test_215() { # for bugs 18102, 21079, 21517
18888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18889
18890         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18891         local P='[1-9][0-9]*'           # positive numeric
18892         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18893         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18894         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18895         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18896
18897         local L1 # regexp for 1st line
18898         local L2 # regexp for 2nd line (optional)
18899         local BR # regexp for the rest (body)
18900
18901         # lnet.stats should look as 11 space-separated non-negative numerics
18902         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18903         create_lnet_proc_files "stats"
18904         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18905         remove_lnet_proc_files "stats"
18906
18907         # lnet.routes should look like this:
18908         # Routing disabled/enabled
18909         # net hops priority state router
18910         # where net is a string like tcp0, hops > 0, priority >= 0,
18911         # state is up/down,
18912         # router is a string like 192.168.1.1@tcp2
18913         L1="^Routing (disabled|enabled)$"
18914         L2="^net +hops +priority +state +router$"
18915         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18916         create_lnet_proc_files "routes"
18917         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18918         remove_lnet_proc_files "routes"
18919
18920         # lnet.routers should look like this:
18921         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18922         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18923         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18924         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18925         L1="^ref +rtr_ref +alive +router$"
18926         BR="^$P +$P +(up|down) +$NID$"
18927         create_lnet_proc_files "routers"
18928         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18929         remove_lnet_proc_files "routers"
18930
18931         # lnet.peers should look like this:
18932         # nid refs state last max rtr min tx min queue
18933         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18934         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18935         # numeric (0 or >0 or <0), queue >= 0.
18936         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18937         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18938         create_lnet_proc_files "peers"
18939         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18940         remove_lnet_proc_files "peers"
18941
18942         # lnet.buffers  should look like this:
18943         # pages count credits min
18944         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18945         L1="^pages +count +credits +min$"
18946         BR="^ +$N +$N +$I +$I$"
18947         create_lnet_proc_files "buffers"
18948         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18949         remove_lnet_proc_files "buffers"
18950
18951         # lnet.nis should look like this:
18952         # nid status alive refs peer rtr max tx min
18953         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18954         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18955         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18956         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18957         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18958         create_lnet_proc_files "nis"
18959         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18960         remove_lnet_proc_files "nis"
18961
18962         # can we successfully write to lnet.stats?
18963         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18964 }
18965 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18966
18967 test_216() { # bug 20317
18968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18969         remote_ost_nodsh && skip "remote OST with nodsh"
18970
18971         local node
18972         local facets=$(get_facets OST)
18973         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18974
18975         save_lustre_params client "osc.*.contention_seconds" > $p
18976         save_lustre_params $facets \
18977                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18978         save_lustre_params $facets \
18979                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18980         save_lustre_params $facets \
18981                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18982         clear_stats osc.*.osc_stats
18983
18984         # agressive lockless i/o settings
18985         do_nodes $(comma_list $(osts_nodes)) \
18986                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18987                         ldlm.namespaces.filter-*.contended_locks=0 \
18988                         ldlm.namespaces.filter-*.contention_seconds=60"
18989         lctl set_param -n osc.*.contention_seconds=60
18990
18991         $DIRECTIO write $DIR/$tfile 0 10 4096
18992         $CHECKSTAT -s 40960 $DIR/$tfile
18993
18994         # disable lockless i/o
18995         do_nodes $(comma_list $(osts_nodes)) \
18996                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18997                         ldlm.namespaces.filter-*.contended_locks=32 \
18998                         ldlm.namespaces.filter-*.contention_seconds=0"
18999         lctl set_param -n osc.*.contention_seconds=0
19000         clear_stats osc.*.osc_stats
19001
19002         dd if=/dev/zero of=$DIR/$tfile count=0
19003         $CHECKSTAT -s 0 $DIR/$tfile
19004
19005         restore_lustre_params <$p
19006         rm -f $p
19007         rm $DIR/$tfile
19008 }
19009 run_test 216 "check lockless direct write updates file size and kms correctly"
19010
19011 test_217() { # bug 22430
19012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19013
19014         local node
19015         local nid
19016
19017         for node in $(nodes_list); do
19018                 nid=$(host_nids_address $node $NETTYPE)
19019                 if [[ $nid = *-* ]] ; then
19020                         echo "lctl ping $(h2nettype $nid)"
19021                         lctl ping $(h2nettype $nid)
19022                 else
19023                         echo "skipping $node (no hyphen detected)"
19024                 fi
19025         done
19026 }
19027 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19028
19029 test_218() {
19030        # do directio so as not to populate the page cache
19031        log "creating a 10 Mb file"
19032        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19033        log "starting reads"
19034        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19035        log "truncating the file"
19036        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19037        log "killing dd"
19038        kill %+ || true # reads might have finished
19039        echo "wait until dd is finished"
19040        wait
19041        log "removing the temporary file"
19042        rm -rf $DIR/$tfile || error "tmp file removal failed"
19043 }
19044 run_test 218 "parallel read and truncate should not deadlock"
19045
19046 test_219() {
19047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19048
19049         # write one partial page
19050         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19051         # set no grant so vvp_io_commit_write will do sync write
19052         $LCTL set_param fail_loc=0x411
19053         # write a full page at the end of file
19054         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19055
19056         $LCTL set_param fail_loc=0
19057         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19058         $LCTL set_param fail_loc=0x411
19059         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19060
19061         # LU-4201
19062         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19063         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19064 }
19065 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19066
19067 test_220() { #LU-325
19068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19069         remote_ost_nodsh && skip "remote OST with nodsh"
19070         remote_mds_nodsh && skip "remote MDS with nodsh"
19071         remote_mgs_nodsh && skip "remote MGS with nodsh"
19072
19073         local OSTIDX=0
19074
19075         # create on MDT0000 so the last_id and next_id are correct
19076         mkdir_on_mdt0 $DIR/$tdir
19077         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19078         OST=${OST%_UUID}
19079
19080         # on the mdt's osc
19081         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19082         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19083                         osp.$mdtosc_proc1.prealloc_last_id)
19084         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19085                         osp.$mdtosc_proc1.prealloc_next_id)
19086
19087         $LFS df -i
19088
19089         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19090         #define OBD_FAIL_OST_ENOINO              0x229
19091         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19092         create_pool $FSNAME.$TESTNAME || return 1
19093         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19094
19095         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19096
19097         MDSOBJS=$((last_id - next_id))
19098         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19099
19100         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19101         echo "OST still has $count kbytes free"
19102
19103         echo "create $MDSOBJS files @next_id..."
19104         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19105
19106         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19107                         osp.$mdtosc_proc1.prealloc_last_id)
19108         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19109                         osp.$mdtosc_proc1.prealloc_next_id)
19110
19111         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19112         $LFS df -i
19113
19114         echo "cleanup..."
19115
19116         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19117         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19118
19119         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19120                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19121         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19122                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19123         echo "unlink $MDSOBJS files @$next_id..."
19124         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19125 }
19126 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19127
19128 test_221() {
19129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19130
19131         dd if=`which date` of=$MOUNT/date oflag=sync
19132         chmod +x $MOUNT/date
19133
19134         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19135         $LCTL set_param fail_loc=0x80001401
19136
19137         $MOUNT/date > /dev/null
19138         rm -f $MOUNT/date
19139 }
19140 run_test 221 "make sure fault and truncate race to not cause OOM"
19141
19142 test_222a () {
19143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19144
19145         rm -rf $DIR/$tdir
19146         test_mkdir $DIR/$tdir
19147         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19148         createmany -o $DIR/$tdir/$tfile 10
19149         cancel_lru_locks mdc
19150         cancel_lru_locks osc
19151         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19152         $LCTL set_param fail_loc=0x31a
19153         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19154         $LCTL set_param fail_loc=0
19155         rm -r $DIR/$tdir
19156 }
19157 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19158
19159 test_222b () {
19160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19161
19162         rm -rf $DIR/$tdir
19163         test_mkdir $DIR/$tdir
19164         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19165         createmany -o $DIR/$tdir/$tfile 10
19166         cancel_lru_locks mdc
19167         cancel_lru_locks osc
19168         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19169         $LCTL set_param fail_loc=0x31a
19170         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19171         $LCTL set_param fail_loc=0
19172 }
19173 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19174
19175 test_223 () {
19176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19177
19178         rm -rf $DIR/$tdir
19179         test_mkdir $DIR/$tdir
19180         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19181         createmany -o $DIR/$tdir/$tfile 10
19182         cancel_lru_locks mdc
19183         cancel_lru_locks osc
19184         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19185         $LCTL set_param fail_loc=0x31b
19186         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19187         $LCTL set_param fail_loc=0
19188         rm -r $DIR/$tdir
19189 }
19190 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19191
19192 test_224a() { # LU-1039, MRP-303
19193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19194         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19195         $LCTL set_param fail_loc=0x508
19196         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19197         $LCTL set_param fail_loc=0
19198         df $DIR
19199 }
19200 run_test 224a "Don't panic on bulk IO failure"
19201
19202 test_224bd_sub() { # LU-1039, MRP-303
19203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19204         local timeout=$1
19205
19206         shift
19207         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19208
19209         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19210
19211         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19212         cancel_lru_locks osc
19213         set_checksums 0
19214         stack_trap "set_checksums $ORIG_CSUM" EXIT
19215         local at_max_saved=0
19216
19217         # adaptive timeouts may prevent seeing the issue
19218         if at_is_enabled; then
19219                 at_max_saved=$(at_max_get mds)
19220                 at_max_set 0 mds client
19221                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19222         fi
19223
19224         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19225         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19226         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19227
19228         do_facet ost1 $LCTL set_param fail_loc=0
19229         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19230         df $DIR
19231 }
19232
19233 test_224b() {
19234         test_224bd_sub 3 error "dd failed"
19235 }
19236 run_test 224b "Don't panic on bulk IO failure"
19237
19238 test_224c() { # LU-6441
19239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19240         remote_mds_nodsh && skip "remote MDS with nodsh"
19241
19242         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19243         save_writethrough $p
19244         set_cache writethrough on
19245
19246         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19247         local at_max=$($LCTL get_param -n at_max)
19248         local timeout=$($LCTL get_param -n timeout)
19249         local test_at="at_max"
19250         local param_at="$FSNAME.sys.at_max"
19251         local test_timeout="timeout"
19252         local param_timeout="$FSNAME.sys.timeout"
19253
19254         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19255
19256         set_persistent_param_and_check client "$test_at" "$param_at" 0
19257         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19258
19259         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19260         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19261         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19262         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19263         sync
19264         do_facet ost1 "$LCTL set_param fail_loc=0"
19265
19266         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19267         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19268                 $timeout
19269
19270         $LCTL set_param -n $pages_per_rpc
19271         restore_lustre_params < $p
19272         rm -f $p
19273 }
19274 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19275
19276 test_224d() { # LU-11169
19277         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19278 }
19279 run_test 224d "Don't corrupt data on bulk IO timeout"
19280
19281 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19282 test_225a () {
19283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19284         if [ -z ${MDSSURVEY} ]; then
19285                 skip_env "mds-survey not found"
19286         fi
19287         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19288                 skip "Need MDS version at least 2.2.51"
19289
19290         local mds=$(facet_host $SINGLEMDS)
19291         local target=$(do_nodes $mds 'lctl dl' |
19292                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19293
19294         local cmd1="file_count=1000 thrhi=4"
19295         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19296         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19297         local cmd="$cmd1 $cmd2 $cmd3"
19298
19299         rm -f ${TMP}/mds_survey*
19300         echo + $cmd
19301         eval $cmd || error "mds-survey with zero-stripe failed"
19302         cat ${TMP}/mds_survey*
19303         rm -f ${TMP}/mds_survey*
19304 }
19305 run_test 225a "Metadata survey sanity with zero-stripe"
19306
19307 test_225b () {
19308         if [ -z ${MDSSURVEY} ]; then
19309                 skip_env "mds-survey not found"
19310         fi
19311         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19312                 skip "Need MDS version at least 2.2.51"
19313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19314         remote_mds_nodsh && skip "remote MDS with nodsh"
19315         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19316                 skip_env "Need to mount OST to test"
19317         fi
19318
19319         local mds=$(facet_host $SINGLEMDS)
19320         local target=$(do_nodes $mds 'lctl dl' |
19321                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19322
19323         local cmd1="file_count=1000 thrhi=4"
19324         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19325         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19326         local cmd="$cmd1 $cmd2 $cmd3"
19327
19328         rm -f ${TMP}/mds_survey*
19329         echo + $cmd
19330         eval $cmd || error "mds-survey with stripe_count failed"
19331         cat ${TMP}/mds_survey*
19332         rm -f ${TMP}/mds_survey*
19333 }
19334 run_test 225b "Metadata survey sanity with stripe_count = 1"
19335
19336 mcreate_path2fid () {
19337         local mode=$1
19338         local major=$2
19339         local minor=$3
19340         local name=$4
19341         local desc=$5
19342         local path=$DIR/$tdir/$name
19343         local fid
19344         local rc
19345         local fid_path
19346
19347         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19348                 error "cannot create $desc"
19349
19350         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19351         rc=$?
19352         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19353
19354         fid_path=$($LFS fid2path $MOUNT $fid)
19355         rc=$?
19356         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19357
19358         [ "$path" == "$fid_path" ] ||
19359                 error "fid2path returned $fid_path, expected $path"
19360
19361         echo "pass with $path and $fid"
19362 }
19363
19364 test_226a () {
19365         rm -rf $DIR/$tdir
19366         mkdir -p $DIR/$tdir
19367
19368         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19369         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19370         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19371         mcreate_path2fid 0040666 0 0 dir "directory"
19372         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19373         mcreate_path2fid 0100666 0 0 file "regular file"
19374         mcreate_path2fid 0120666 0 0 link "symbolic link"
19375         mcreate_path2fid 0140666 0 0 sock "socket"
19376 }
19377 run_test 226a "call path2fid and fid2path on files of all type"
19378
19379 test_226b () {
19380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19381
19382         local MDTIDX=1
19383
19384         rm -rf $DIR/$tdir
19385         mkdir -p $DIR/$tdir
19386         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19387                 error "create remote directory failed"
19388         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19389         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19390                                 "character special file (null)"
19391         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19392                                 "character special file (no device)"
19393         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19394         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19395                                 "block special file (loop)"
19396         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19397         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19398         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19399 }
19400 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19401
19402 test_226c () {
19403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19404         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19405                 skip "Need MDS version at least 2.13.55"
19406
19407         local submnt=/mnt/submnt
19408         local srcfile=/etc/passwd
19409         local dstfile=$submnt/passwd
19410         local path
19411         local fid
19412
19413         rm -rf $DIR/$tdir
19414         rm -rf $submnt
19415         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19416                 error "create remote directory failed"
19417         mkdir -p $submnt || error "create $submnt failed"
19418         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19419                 error "mount $submnt failed"
19420         stack_trap "umount $submnt" EXIT
19421
19422         cp $srcfile $dstfile
19423         fid=$($LFS path2fid $dstfile)
19424         path=$($LFS fid2path $submnt "$fid")
19425         [ "$path" = "$dstfile" ] ||
19426                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19427 }
19428 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19429
19430 # LU-1299 Executing or running ldd on a truncated executable does not
19431 # cause an out-of-memory condition.
19432 test_227() {
19433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19434         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19435
19436         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19437         chmod +x $MOUNT/date
19438
19439         $MOUNT/date > /dev/null
19440         ldd $MOUNT/date > /dev/null
19441         rm -f $MOUNT/date
19442 }
19443 run_test 227 "running truncated executable does not cause OOM"
19444
19445 # LU-1512 try to reuse idle OI blocks
19446 test_228a() {
19447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19448         remote_mds_nodsh && skip "remote MDS with nodsh"
19449         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19450
19451         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19452         local myDIR=$DIR/$tdir
19453
19454         mkdir -p $myDIR
19455         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19456         $LCTL set_param fail_loc=0x80001002
19457         createmany -o $myDIR/t- 10000
19458         $LCTL set_param fail_loc=0
19459         # The guard is current the largest FID holder
19460         touch $myDIR/guard
19461         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19462                     tr -d '[')
19463         local IDX=$(($SEQ % 64))
19464
19465         do_facet $SINGLEMDS sync
19466         # Make sure journal flushed.
19467         sleep 6
19468         local blk1=$(do_facet $SINGLEMDS \
19469                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19470                      grep Blockcount | awk '{print $4}')
19471
19472         # Remove old files, some OI blocks will become idle.
19473         unlinkmany $myDIR/t- 10000
19474         # Create new files, idle OI blocks should be reused.
19475         createmany -o $myDIR/t- 2000
19476         do_facet $SINGLEMDS sync
19477         # Make sure journal flushed.
19478         sleep 6
19479         local blk2=$(do_facet $SINGLEMDS \
19480                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19481                      grep Blockcount | awk '{print $4}')
19482
19483         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19484 }
19485 run_test 228a "try to reuse idle OI blocks"
19486
19487 test_228b() {
19488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19489         remote_mds_nodsh && skip "remote MDS with nodsh"
19490         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19491
19492         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19493         local myDIR=$DIR/$tdir
19494
19495         mkdir -p $myDIR
19496         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19497         $LCTL set_param fail_loc=0x80001002
19498         createmany -o $myDIR/t- 10000
19499         $LCTL set_param fail_loc=0
19500         # The guard is current the largest FID holder
19501         touch $myDIR/guard
19502         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19503                     tr -d '[')
19504         local IDX=$(($SEQ % 64))
19505
19506         do_facet $SINGLEMDS sync
19507         # Make sure journal flushed.
19508         sleep 6
19509         local blk1=$(do_facet $SINGLEMDS \
19510                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19511                      grep Blockcount | awk '{print $4}')
19512
19513         # Remove old files, some OI blocks will become idle.
19514         unlinkmany $myDIR/t- 10000
19515
19516         # stop the MDT
19517         stop $SINGLEMDS || error "Fail to stop MDT."
19518         # remount the MDT
19519         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
19520                 error "Fail to start MDT."
19521
19522         df $MOUNT || error "Fail to df."
19523         # Create new files, idle OI blocks should be reused.
19524         createmany -o $myDIR/t- 2000
19525         do_facet $SINGLEMDS sync
19526         # Make sure journal flushed.
19527         sleep 6
19528         local blk2=$(do_facet $SINGLEMDS \
19529                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19530                      grep Blockcount | awk '{print $4}')
19531
19532         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19533 }
19534 run_test 228b "idle OI blocks can be reused after MDT restart"
19535
19536 #LU-1881
19537 test_228c() {
19538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19539         remote_mds_nodsh && skip "remote MDS with nodsh"
19540         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19541
19542         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19543         local myDIR=$DIR/$tdir
19544
19545         mkdir -p $myDIR
19546         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19547         $LCTL set_param fail_loc=0x80001002
19548         # 20000 files can guarantee there are index nodes in the OI file
19549         createmany -o $myDIR/t- 20000
19550         $LCTL set_param fail_loc=0
19551         # The guard is current the largest FID holder
19552         touch $myDIR/guard
19553         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19554                     tr -d '[')
19555         local IDX=$(($SEQ % 64))
19556
19557         do_facet $SINGLEMDS sync
19558         # Make sure journal flushed.
19559         sleep 6
19560         local blk1=$(do_facet $SINGLEMDS \
19561                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19562                      grep Blockcount | awk '{print $4}')
19563
19564         # Remove old files, some OI blocks will become idle.
19565         unlinkmany $myDIR/t- 20000
19566         rm -f $myDIR/guard
19567         # The OI file should become empty now
19568
19569         # Create new files, idle OI blocks should be reused.
19570         createmany -o $myDIR/t- 2000
19571         do_facet $SINGLEMDS sync
19572         # Make sure journal flushed.
19573         sleep 6
19574         local blk2=$(do_facet $SINGLEMDS \
19575                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19576                      grep Blockcount | awk '{print $4}')
19577
19578         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19579 }
19580 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19581
19582 test_229() { # LU-2482, LU-3448
19583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19584         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19585         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19586                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19587
19588         rm -f $DIR/$tfile
19589
19590         # Create a file with a released layout and stripe count 2.
19591         $MULTIOP $DIR/$tfile H2c ||
19592                 error "failed to create file with released layout"
19593
19594         $LFS getstripe -v $DIR/$tfile
19595
19596         local pattern=$($LFS getstripe -L $DIR/$tfile)
19597         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19598
19599         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19600                 error "getstripe"
19601         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19602         stat $DIR/$tfile || error "failed to stat released file"
19603
19604         chown $RUNAS_ID $DIR/$tfile ||
19605                 error "chown $RUNAS_ID $DIR/$tfile failed"
19606
19607         chgrp $RUNAS_ID $DIR/$tfile ||
19608                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19609
19610         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19611         rm $DIR/$tfile || error "failed to remove released file"
19612 }
19613 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19614
19615 test_230a() {
19616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19617         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19618         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19619                 skip "Need MDS version at least 2.11.52"
19620
19621         local MDTIDX=1
19622
19623         test_mkdir $DIR/$tdir
19624         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19625         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19626         [ $mdt_idx -ne 0 ] &&
19627                 error "create local directory on wrong MDT $mdt_idx"
19628
19629         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19630                         error "create remote directory failed"
19631         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19632         [ $mdt_idx -ne $MDTIDX ] &&
19633                 error "create remote directory on wrong MDT $mdt_idx"
19634
19635         createmany -o $DIR/$tdir/test_230/t- 10 ||
19636                 error "create files on remote directory failed"
19637         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19638         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19639         rm -r $DIR/$tdir || error "unlink remote directory failed"
19640 }
19641 run_test 230a "Create remote directory and files under the remote directory"
19642
19643 test_230b() {
19644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19645         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19646         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19647                 skip "Need MDS version at least 2.11.52"
19648
19649         local MDTIDX=1
19650         local mdt_index
19651         local i
19652         local file
19653         local pid
19654         local stripe_count
19655         local migrate_dir=$DIR/$tdir/migrate_dir
19656         local other_dir=$DIR/$tdir/other_dir
19657
19658         test_mkdir $DIR/$tdir
19659         test_mkdir -i0 -c1 $migrate_dir
19660         test_mkdir -i0 -c1 $other_dir
19661         for ((i=0; i<10; i++)); do
19662                 mkdir -p $migrate_dir/dir_${i}
19663                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19664                         error "create files under remote dir failed $i"
19665         done
19666
19667         cp /etc/passwd $migrate_dir/$tfile
19668         cp /etc/passwd $other_dir/$tfile
19669         chattr +SAD $migrate_dir
19670         chattr +SAD $migrate_dir/$tfile
19671
19672         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19673         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19674         local old_dir_mode=$(stat -c%f $migrate_dir)
19675         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19676
19677         mkdir -p $migrate_dir/dir_default_stripe2
19678         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19679         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19680
19681         mkdir -p $other_dir
19682         ln $migrate_dir/$tfile $other_dir/luna
19683         ln $migrate_dir/$tfile $migrate_dir/sofia
19684         ln $other_dir/$tfile $migrate_dir/david
19685         ln -s $migrate_dir/$tfile $other_dir/zachary
19686         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19687         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19688
19689         local len
19690         local lnktgt
19691
19692         # inline symlink
19693         for len in 58 59 60; do
19694                 lnktgt=$(str_repeat 'l' $len)
19695                 touch $migrate_dir/$lnktgt
19696                 ln -s $lnktgt $migrate_dir/${len}char_ln
19697         done
19698
19699         # PATH_MAX
19700         for len in 4094 4095; do
19701                 lnktgt=$(str_repeat 'l' $len)
19702                 ln -s $lnktgt $migrate_dir/${len}char_ln
19703         done
19704
19705         # NAME_MAX
19706         for len in 254 255; do
19707                 touch $migrate_dir/$(str_repeat 'l' $len)
19708         done
19709
19710         $LFS migrate -m $MDTIDX $migrate_dir ||
19711                 error "fails on migrating remote dir to MDT1"
19712
19713         echo "migratate to MDT1, then checking.."
19714         for ((i = 0; i < 10; i++)); do
19715                 for file in $(find $migrate_dir/dir_${i}); do
19716                         mdt_index=$($LFS getstripe -m $file)
19717                         # broken symlink getstripe will fail
19718                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19719                                 error "$file is not on MDT${MDTIDX}"
19720                 done
19721         done
19722
19723         # the multiple link file should still in MDT0
19724         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19725         [ $mdt_index == 0 ] ||
19726                 error "$file is not on MDT${MDTIDX}"
19727
19728         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19729         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19730                 error " expect $old_dir_flag get $new_dir_flag"
19731
19732         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19733         [ "$old_file_flag" = "$new_file_flag" ] ||
19734                 error " expect $old_file_flag get $new_file_flag"
19735
19736         local new_dir_mode=$(stat -c%f $migrate_dir)
19737         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19738                 error "expect mode $old_dir_mode get $new_dir_mode"
19739
19740         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19741         [ "$old_file_mode" = "$new_file_mode" ] ||
19742                 error "expect mode $old_file_mode get $new_file_mode"
19743
19744         diff /etc/passwd $migrate_dir/$tfile ||
19745                 error "$tfile different after migration"
19746
19747         diff /etc/passwd $other_dir/luna ||
19748                 error "luna different after migration"
19749
19750         diff /etc/passwd $migrate_dir/sofia ||
19751                 error "sofia different after migration"
19752
19753         diff /etc/passwd $migrate_dir/david ||
19754                 error "david different after migration"
19755
19756         diff /etc/passwd $other_dir/zachary ||
19757                 error "zachary different after migration"
19758
19759         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19760                 error "${tfile}_ln different after migration"
19761
19762         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19763                 error "${tfile}_ln_other different after migration"
19764
19765         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19766         [ $stripe_count = 2 ] ||
19767                 error "dir strpe_count $d != 2 after migration."
19768
19769         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19770         [ $stripe_count = 2 ] ||
19771                 error "file strpe_count $d != 2 after migration."
19772
19773         #migrate back to MDT0
19774         MDTIDX=0
19775
19776         $LFS migrate -m $MDTIDX $migrate_dir ||
19777                 error "fails on migrating remote dir to MDT0"
19778
19779         echo "migrate back to MDT0, checking.."
19780         for file in $(find $migrate_dir); do
19781                 mdt_index=$($LFS getstripe -m $file)
19782                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19783                         error "$file is not on MDT${MDTIDX}"
19784         done
19785
19786         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19787         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19788                 error " expect $old_dir_flag get $new_dir_flag"
19789
19790         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19791         [ "$old_file_flag" = "$new_file_flag" ] ||
19792                 error " expect $old_file_flag get $new_file_flag"
19793
19794         local new_dir_mode=$(stat -c%f $migrate_dir)
19795         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19796                 error "expect mode $old_dir_mode get $new_dir_mode"
19797
19798         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19799         [ "$old_file_mode" = "$new_file_mode" ] ||
19800                 error "expect mode $old_file_mode get $new_file_mode"
19801
19802         diff /etc/passwd ${migrate_dir}/$tfile ||
19803                 error "$tfile different after migration"
19804
19805         diff /etc/passwd ${other_dir}/luna ||
19806                 error "luna different after migration"
19807
19808         diff /etc/passwd ${migrate_dir}/sofia ||
19809                 error "sofia different after migration"
19810
19811         diff /etc/passwd ${other_dir}/zachary ||
19812                 error "zachary different after migration"
19813
19814         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19815                 error "${tfile}_ln different after migration"
19816
19817         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19818                 error "${tfile}_ln_other different after migration"
19819
19820         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19821         [ $stripe_count = 2 ] ||
19822                 error "dir strpe_count $d != 2 after migration."
19823
19824         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19825         [ $stripe_count = 2 ] ||
19826                 error "file strpe_count $d != 2 after migration."
19827
19828         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19829 }
19830 run_test 230b "migrate directory"
19831
19832 test_230c() {
19833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19834         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19835         remote_mds_nodsh && skip "remote MDS with nodsh"
19836         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19837                 skip "Need MDS version at least 2.11.52"
19838
19839         local MDTIDX=1
19840         local total=3
19841         local mdt_index
19842         local file
19843         local migrate_dir=$DIR/$tdir/migrate_dir
19844
19845         #If migrating directory fails in the middle, all entries of
19846         #the directory is still accessiable.
19847         test_mkdir $DIR/$tdir
19848         test_mkdir -i0 -c1 $migrate_dir
19849         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19850         stat $migrate_dir
19851         createmany -o $migrate_dir/f $total ||
19852                 error "create files under ${migrate_dir} failed"
19853
19854         # fail after migrating top dir, and this will fail only once, so the
19855         # first sub file migration will fail (currently f3), others succeed.
19856         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19857         do_facet mds1 lctl set_param fail_loc=0x1801
19858         local t=$(ls $migrate_dir | wc -l)
19859         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19860                 error "migrate should fail"
19861         local u=$(ls $migrate_dir | wc -l)
19862         [ "$u" == "$t" ] || error "$u != $t during migration"
19863
19864         # add new dir/file should succeed
19865         mkdir $migrate_dir/dir ||
19866                 error "mkdir failed under migrating directory"
19867         touch $migrate_dir/file ||
19868                 error "create file failed under migrating directory"
19869
19870         # add file with existing name should fail
19871         for file in $migrate_dir/f*; do
19872                 stat $file > /dev/null || error "stat $file failed"
19873                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19874                         error "open(O_CREAT|O_EXCL) $file should fail"
19875                 $MULTIOP $file m && error "create $file should fail"
19876                 touch $DIR/$tdir/remote_dir/$tfile ||
19877                         error "touch $tfile failed"
19878                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19879                         error "link $file should fail"
19880                 mdt_index=$($LFS getstripe -m $file)
19881                 if [ $mdt_index == 0 ]; then
19882                         # file failed to migrate is not allowed to rename to
19883                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19884                                 error "rename to $file should fail"
19885                 else
19886                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19887                                 error "rename to $file failed"
19888                 fi
19889                 echo hello >> $file || error "write $file failed"
19890         done
19891
19892         # resume migration with different options should fail
19893         $LFS migrate -m 0 $migrate_dir &&
19894                 error "migrate -m 0 $migrate_dir should fail"
19895
19896         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19897                 error "migrate -c 2 $migrate_dir should fail"
19898
19899         # resume migration should succeed
19900         $LFS migrate -m $MDTIDX $migrate_dir ||
19901                 error "migrate $migrate_dir failed"
19902
19903         echo "Finish migration, then checking.."
19904         for file in $(find $migrate_dir); do
19905                 mdt_index=$($LFS getstripe -m $file)
19906                 [ $mdt_index == $MDTIDX ] ||
19907                         error "$file is not on MDT${MDTIDX}"
19908         done
19909
19910         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19911 }
19912 run_test 230c "check directory accessiblity if migration failed"
19913
19914 test_230d() {
19915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19916         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19917         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19918                 skip "Need MDS version at least 2.11.52"
19919         # LU-11235
19920         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19921
19922         local migrate_dir=$DIR/$tdir/migrate_dir
19923         local old_index
19924         local new_index
19925         local old_count
19926         local new_count
19927         local new_hash
19928         local mdt_index
19929         local i
19930         local j
19931
19932         old_index=$((RANDOM % MDSCOUNT))
19933         old_count=$((MDSCOUNT - old_index))
19934         new_index=$((RANDOM % MDSCOUNT))
19935         new_count=$((MDSCOUNT - new_index))
19936         new_hash=1 # for all_char
19937
19938         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19939         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19940
19941         test_mkdir $DIR/$tdir
19942         test_mkdir -i $old_index -c $old_count $migrate_dir
19943
19944         for ((i=0; i<100; i++)); do
19945                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19946                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19947                         error "create files under remote dir failed $i"
19948         done
19949
19950         echo -n "Migrate from MDT$old_index "
19951         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19952         echo -n "to MDT$new_index"
19953         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19954         echo
19955
19956         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19957         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19958                 error "migrate remote dir error"
19959
19960         echo "Finish migration, then checking.."
19961         for file in $(find $migrate_dir -maxdepth 1); do
19962                 mdt_index=$($LFS getstripe -m $file)
19963                 if [ $mdt_index -lt $new_index ] ||
19964                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19965                         error "$file is on MDT$mdt_index"
19966                 fi
19967         done
19968
19969         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19970 }
19971 run_test 230d "check migrate big directory"
19972
19973 test_230e() {
19974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19975         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19976         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19977                 skip "Need MDS version at least 2.11.52"
19978
19979         local i
19980         local j
19981         local a_fid
19982         local b_fid
19983
19984         mkdir_on_mdt0 $DIR/$tdir
19985         mkdir $DIR/$tdir/migrate_dir
19986         mkdir $DIR/$tdir/other_dir
19987         touch $DIR/$tdir/migrate_dir/a
19988         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19989         ls $DIR/$tdir/other_dir
19990
19991         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19992                 error "migrate dir fails"
19993
19994         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19995         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19996
19997         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19998         [ $mdt_index == 0 ] || error "a is not on MDT0"
19999
20000         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20001                 error "migrate dir fails"
20002
20003         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20004         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20005
20006         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20007         [ $mdt_index == 1 ] || error "a is not on MDT1"
20008
20009         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20010         [ $mdt_index == 1 ] || error "b is not on MDT1"
20011
20012         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20013         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20014
20015         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20016
20017         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20018 }
20019 run_test 230e "migrate mulitple local link files"
20020
20021 test_230f() {
20022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20023         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20024         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20025                 skip "Need MDS version at least 2.11.52"
20026
20027         local a_fid
20028         local ln_fid
20029
20030         mkdir -p $DIR/$tdir
20031         mkdir $DIR/$tdir/migrate_dir
20032         $LFS mkdir -i1 $DIR/$tdir/other_dir
20033         touch $DIR/$tdir/migrate_dir/a
20034         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20035         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20036         ls $DIR/$tdir/other_dir
20037
20038         # a should be migrated to MDT1, since no other links on MDT0
20039         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20040                 error "#1 migrate dir fails"
20041         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20042         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20043         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20044         [ $mdt_index == 1 ] || error "a is not on MDT1"
20045
20046         # a should stay on MDT1, because it is a mulitple link file
20047         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20048                 error "#2 migrate dir fails"
20049         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20050         [ $mdt_index == 1 ] || error "a is not on MDT1"
20051
20052         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20053                 error "#3 migrate dir fails"
20054
20055         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20056         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20057         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20058
20059         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20060         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20061
20062         # a should be migrated to MDT0, since no other links on MDT1
20063         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20064                 error "#4 migrate dir fails"
20065         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20066         [ $mdt_index == 0 ] || error "a is not on MDT0"
20067
20068         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20069 }
20070 run_test 230f "migrate mulitple remote link files"
20071
20072 test_230g() {
20073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20074         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20075         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20076                 skip "Need MDS version at least 2.11.52"
20077
20078         mkdir -p $DIR/$tdir/migrate_dir
20079
20080         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20081                 error "migrating dir to non-exist MDT succeeds"
20082         true
20083 }
20084 run_test 230g "migrate dir to non-exist MDT"
20085
20086 test_230h() {
20087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20088         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20089         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20090                 skip "Need MDS version at least 2.11.52"
20091
20092         local mdt_index
20093
20094         mkdir -p $DIR/$tdir/migrate_dir
20095
20096         $LFS migrate -m1 $DIR &&
20097                 error "migrating mountpoint1 should fail"
20098
20099         $LFS migrate -m1 $DIR/$tdir/.. &&
20100                 error "migrating mountpoint2 should fail"
20101
20102         # same as mv
20103         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20104                 error "migrating $tdir/migrate_dir/.. should fail"
20105
20106         true
20107 }
20108 run_test 230h "migrate .. and root"
20109
20110 test_230i() {
20111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20113         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20114                 skip "Need MDS version at least 2.11.52"
20115
20116         mkdir -p $DIR/$tdir/migrate_dir
20117
20118         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20119                 error "migration fails with a tailing slash"
20120
20121         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20122                 error "migration fails with two tailing slashes"
20123 }
20124 run_test 230i "lfs migrate -m tolerates trailing slashes"
20125
20126 test_230j() {
20127         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20128         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20129                 skip "Need MDS version at least 2.11.52"
20130
20131         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20132         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20133                 error "create $tfile failed"
20134         cat /etc/passwd > $DIR/$tdir/$tfile
20135
20136         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20137
20138         cmp /etc/passwd $DIR/$tdir/$tfile ||
20139                 error "DoM file mismatch after migration"
20140 }
20141 run_test 230j "DoM file data not changed after dir migration"
20142
20143 test_230k() {
20144         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20145         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20146                 skip "Need MDS version at least 2.11.56"
20147
20148         local total=20
20149         local files_on_starting_mdt=0
20150
20151         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20152         $LFS getdirstripe $DIR/$tdir
20153         for i in $(seq $total); do
20154                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20155                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20156                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20157         done
20158
20159         echo "$files_on_starting_mdt files on MDT0"
20160
20161         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20162         $LFS getdirstripe $DIR/$tdir
20163
20164         files_on_starting_mdt=0
20165         for i in $(seq $total); do
20166                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20167                         error "file $tfile.$i mismatch after migration"
20168                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20169                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20170         done
20171
20172         echo "$files_on_starting_mdt files on MDT1 after migration"
20173         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20174
20175         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20176         $LFS getdirstripe $DIR/$tdir
20177
20178         files_on_starting_mdt=0
20179         for i in $(seq $total); do
20180                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20181                         error "file $tfile.$i mismatch after 2nd migration"
20182                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20183                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20184         done
20185
20186         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20187         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20188
20189         true
20190 }
20191 run_test 230k "file data not changed after dir migration"
20192
20193 test_230l() {
20194         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20195         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20196                 skip "Need MDS version at least 2.11.56"
20197
20198         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20199         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20200                 error "create files under remote dir failed $i"
20201         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20202 }
20203 run_test 230l "readdir between MDTs won't crash"
20204
20205 test_230m() {
20206         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20207         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20208                 skip "Need MDS version at least 2.11.56"
20209
20210         local MDTIDX=1
20211         local mig_dir=$DIR/$tdir/migrate_dir
20212         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20213         local shortstr="b"
20214         local val
20215
20216         echo "Creating files and dirs with xattrs"
20217         test_mkdir $DIR/$tdir
20218         test_mkdir -i0 -c1 $mig_dir
20219         mkdir $mig_dir/dir
20220         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20221                 error "cannot set xattr attr1 on dir"
20222         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20223                 error "cannot set xattr attr2 on dir"
20224         touch $mig_dir/dir/f0
20225         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20226                 error "cannot set xattr attr1 on file"
20227         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20228                 error "cannot set xattr attr2 on file"
20229         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20230         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20231         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20232         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20233         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20234         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20235         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20236         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20237         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20238
20239         echo "Migrating to MDT1"
20240         $LFS migrate -m $MDTIDX $mig_dir ||
20241                 error "fails on migrating dir to MDT1"
20242
20243         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20244         echo "Checking xattrs"
20245         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20246         [ "$val" = $longstr ] ||
20247                 error "expecting xattr1 $longstr on dir, found $val"
20248         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20249         [ "$val" = $shortstr ] ||
20250                 error "expecting xattr2 $shortstr on dir, found $val"
20251         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20252         [ "$val" = $longstr ] ||
20253                 error "expecting xattr1 $longstr on file, found $val"
20254         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20255         [ "$val" = $shortstr ] ||
20256                 error "expecting xattr2 $shortstr on file, found $val"
20257 }
20258 run_test 230m "xattrs not changed after dir migration"
20259
20260 test_230n() {
20261         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20262         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20263                 skip "Need MDS version at least 2.13.53"
20264
20265         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20266         cat /etc/hosts > $DIR/$tdir/$tfile
20267         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20268         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20269
20270         cmp /etc/hosts $DIR/$tdir/$tfile ||
20271                 error "File data mismatch after migration"
20272 }
20273 run_test 230n "Dir migration with mirrored file"
20274
20275 test_230o() {
20276         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20277         [ $MDS1_VERSION -ge $(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 i
20285
20286         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20287
20288         # in case "crush" hash type is not set
20289         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20290
20291         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20292                            mdt.*MDT0000.enable_dir_restripe)
20293         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20294         stack_trap "do_nodes $mdts $LCTL set_param \
20295                     mdt.*.enable_dir_restripe=$restripe_status"
20296
20297         mkdir $DIR/$tdir
20298         createmany -m $DIR/$tdir/f 100 ||
20299                 error "create files under remote dir failed $i"
20300         createmany -d $DIR/$tdir/d 100 ||
20301                 error "create dirs under remote dir failed $i"
20302
20303         for i in $(seq 2 $MDSCOUNT); do
20304                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20305                 $LFS setdirstripe -c $i $DIR/$tdir ||
20306                         error "split -c $i $tdir failed"
20307                 wait_update $HOSTNAME \
20308                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20309                         error "dir split not finished"
20310                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20311                         awk '/migrate/ {sum += $2} END { print sum }')
20312                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20313                 # delta is around total_files/stripe_count
20314                 (( $delta < 200 / (i - 1) + 4 )) ||
20315                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20316         done
20317 }
20318 run_test 230o "dir split"
20319
20320 test_230p() {
20321         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20322         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20323                 skip "Need MDS version at least 2.13.52"
20324
20325         local mdts=$(comma_list $(mdts_nodes))
20326         local timeout=100
20327         local restripe_status
20328         local delta
20329         local c
20330
20331         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20332
20333         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20334
20335         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20336                            mdt.*MDT0000.enable_dir_restripe)
20337         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20338         stack_trap "do_nodes $mdts $LCTL set_param \
20339                     mdt.*.enable_dir_restripe=$restripe_status"
20340
20341         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20342         createmany -m $DIR/$tdir/f 100 ||
20343                 error "create files under remote dir failed"
20344         createmany -d $DIR/$tdir/d 100 ||
20345                 error "create dirs under remote dir failed"
20346
20347         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20348                 local mdt_hash="crush"
20349
20350                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20351                 $LFS setdirstripe -c $c $DIR/$tdir ||
20352                         error "split -c $c $tdir failed"
20353                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20354                         mdt_hash="$mdt_hash,fixed"
20355                 elif [ $c -eq 1 ]; then
20356                         mdt_hash="none"
20357                 fi
20358                 wait_update $HOSTNAME \
20359                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20360                         error "dir merge not finished"
20361                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20362                         awk '/migrate/ {sum += $2} END { print sum }')
20363                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20364                 # delta is around total_files/stripe_count
20365                 (( delta < 200 / c + 4 )) ||
20366                         error "$delta files migrated >= $((200 / c + 4))"
20367         done
20368 }
20369 run_test 230p "dir merge"
20370
20371 test_230q() {
20372         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20373         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20374                 skip "Need MDS version at least 2.13.52"
20375
20376         local mdts=$(comma_list $(mdts_nodes))
20377         local saved_threshold=$(do_facet mds1 \
20378                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20379         local saved_delta=$(do_facet mds1 \
20380                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20381         local threshold=100
20382         local delta=2
20383         local total=0
20384         local stripe_count=0
20385         local stripe_index
20386         local nr_files
20387         local create
20388
20389         # test with fewer files on ZFS
20390         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20391
20392         stack_trap "do_nodes $mdts $LCTL set_param \
20393                     mdt.*.dir_split_count=$saved_threshold"
20394         stack_trap "do_nodes $mdts $LCTL set_param \
20395                     mdt.*.dir_split_delta=$saved_delta"
20396         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20397         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20398         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20399         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20400         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20401         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20402
20403         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20404         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20405
20406         create=$((threshold * 3 / 2))
20407         while [ $stripe_count -lt $MDSCOUNT ]; do
20408                 createmany -m $DIR/$tdir/f $total $create ||
20409                         error "create sub files failed"
20410                 stat $DIR/$tdir > /dev/null
20411                 total=$((total + create))
20412                 stripe_count=$((stripe_count + delta))
20413                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20414
20415                 wait_update $HOSTNAME \
20416                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20417                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20418
20419                 wait_update $HOSTNAME \
20420                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20421                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20422
20423                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20424                 echo "$nr_files/$total files on MDT$stripe_index after split"
20425                 # allow 10% margin of imbalance with crush hash
20426                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20427                         error "$nr_files files on MDT$stripe_index after split"
20428
20429                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20430                 [ $nr_files -eq $total ] ||
20431                         error "total sub files $nr_files != $total"
20432         done
20433
20434         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20435
20436         echo "fixed layout directory won't auto split"
20437         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20438         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20439                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20440         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20441                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20442 }
20443 run_test 230q "dir auto split"
20444
20445 test_230r() {
20446         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20447         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20448         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20449                 skip "Need MDS version at least 2.13.54"
20450
20451         # maximum amount of local locks:
20452         # parent striped dir - 2 locks
20453         # new stripe in parent to migrate to - 1 lock
20454         # source and target - 2 locks
20455         # Total 5 locks for regular file
20456         mkdir -p $DIR/$tdir
20457         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20458         touch $DIR/$tdir/dir1/eee
20459
20460         # create 4 hardlink for 4 more locks
20461         # Total: 9 locks > RS_MAX_LOCKS (8)
20462         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20463         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20464         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20465         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20466         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20467         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20468         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20469         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20470
20471         cancel_lru_locks mdc
20472
20473         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20474                 error "migrate dir fails"
20475
20476         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20477 }
20478 run_test 230r "migrate with too many local locks"
20479
20480 test_230s() {
20481         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
20482                 skip "Need MDS version at least 2.14.52"
20483
20484         local mdts=$(comma_list $(mdts_nodes))
20485         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20486                                 mdt.*MDT0000.enable_dir_restripe)
20487
20488         stack_trap "do_nodes $mdts $LCTL set_param \
20489                     mdt.*.enable_dir_restripe=$restripe_status"
20490
20491         local st
20492         for st in 0 1; do
20493                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20494                 test_mkdir $DIR/$tdir
20495                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20496                         error "$LFS mkdir should return EEXIST if target exists"
20497                 rmdir $DIR/$tdir
20498         done
20499 }
20500 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20501
20502 test_230t()
20503 {
20504         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20505         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20506                 skip "Need MDS version at least 2.14.50"
20507
20508         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20509         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20510         $LFS project -p 1 -s $DIR/$tdir ||
20511                 error "set $tdir project id failed"
20512         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20513                 error "set subdir project id failed"
20514         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20515 }
20516 run_test 230t "migrate directory with project ID set"
20517
20518 test_230u()
20519 {
20520         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20521         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20522                 skip "Need MDS version at least 2.14.53"
20523
20524         local count
20525
20526         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20527         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20528         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20529         for i in $(seq 0 $((MDSCOUNT - 1))); do
20530                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20531                 echo "$count dirs migrated to MDT$i"
20532         done
20533         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20534         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20535 }
20536 run_test 230u "migrate directory by QOS"
20537
20538 test_230v()
20539 {
20540         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20541         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20542                 skip "Need MDS version at least 2.14.53"
20543
20544         local count
20545
20546         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20547         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20548         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20549         for i in $(seq 0 $((MDSCOUNT - 1))); do
20550                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20551                 echo "$count subdirs migrated to MDT$i"
20552                 (( i == 3 )) && (( count > 0 )) &&
20553                         error "subdir shouldn't be migrated to MDT3"
20554         done
20555         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20556         (( count == 3 )) || error "dirs migrated to $count MDTs"
20557 }
20558 run_test 230v "subdir migrated to the MDT where its parent is located"
20559
20560 test_230w() {
20561         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20562         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20563                 skip "Need MDS version at least 2.14.53"
20564
20565         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20566
20567         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20568                 error "migrate failed"
20569
20570         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20571                 error "$tdir stripe count mismatch"
20572
20573         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20574                 error "$tdir/sub is striped"
20575 }
20576 run_test 230w "non-recursive mode dir migration"
20577
20578 test_231a()
20579 {
20580         # For simplicity this test assumes that max_pages_per_rpc
20581         # is the same across all OSCs
20582         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20583         local bulk_size=$((max_pages * PAGE_SIZE))
20584         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20585                                        head -n 1)
20586
20587         mkdir -p $DIR/$tdir
20588         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20589                 error "failed to set stripe with -S ${brw_size}M option"
20590
20591         # clear the OSC stats
20592         $LCTL set_param osc.*.stats=0 &>/dev/null
20593         stop_writeback
20594
20595         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20596         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20597                 oflag=direct &>/dev/null || error "dd failed"
20598
20599         sync; sleep 1; sync # just to be safe
20600         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20601         if [ x$nrpcs != "x1" ]; then
20602                 $LCTL get_param osc.*.stats
20603                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20604         fi
20605
20606         start_writeback
20607         # Drop the OSC cache, otherwise we will read from it
20608         cancel_lru_locks osc
20609
20610         # clear the OSC stats
20611         $LCTL set_param osc.*.stats=0 &>/dev/null
20612
20613         # Client reads $bulk_size.
20614         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20615                 iflag=direct &>/dev/null || error "dd failed"
20616
20617         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20618         if [ x$nrpcs != "x1" ]; then
20619                 $LCTL get_param osc.*.stats
20620                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20621         fi
20622 }
20623 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20624
20625 test_231b() {
20626         mkdir -p $DIR/$tdir
20627         local i
20628         for i in {0..1023}; do
20629                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20630                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20631                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20632         done
20633         sync
20634 }
20635 run_test 231b "must not assert on fully utilized OST request buffer"
20636
20637 test_232a() {
20638         mkdir -p $DIR/$tdir
20639         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20640
20641         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20642         do_facet ost1 $LCTL set_param fail_loc=0x31c
20643
20644         # ignore dd failure
20645         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20646
20647         do_facet ost1 $LCTL set_param fail_loc=0
20648         umount_client $MOUNT || error "umount failed"
20649         mount_client $MOUNT || error "mount failed"
20650         stop ost1 || error "cannot stop ost1"
20651         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20652 }
20653 run_test 232a "failed lock should not block umount"
20654
20655 test_232b() {
20656         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20657                 skip "Need MDS version at least 2.10.58"
20658
20659         mkdir -p $DIR/$tdir
20660         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20661         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20662         sync
20663         cancel_lru_locks osc
20664
20665         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20666         do_facet ost1 $LCTL set_param fail_loc=0x31c
20667
20668         # ignore failure
20669         $LFS data_version $DIR/$tdir/$tfile || true
20670
20671         do_facet ost1 $LCTL set_param fail_loc=0
20672         umount_client $MOUNT || error "umount failed"
20673         mount_client $MOUNT || error "mount failed"
20674         stop ost1 || error "cannot stop ost1"
20675         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20676 }
20677 run_test 232b "failed data version lock should not block umount"
20678
20679 test_233a() {
20680         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20681                 skip "Need MDS version at least 2.3.64"
20682         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20683
20684         local fid=$($LFS path2fid $MOUNT)
20685
20686         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20687                 error "cannot access $MOUNT using its FID '$fid'"
20688 }
20689 run_test 233a "checking that OBF of the FS root succeeds"
20690
20691 test_233b() {
20692         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20693                 skip "Need MDS version at least 2.5.90"
20694         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20695
20696         local fid=$($LFS path2fid $MOUNT/.lustre)
20697
20698         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20699                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20700
20701         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20702         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20703                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20704 }
20705 run_test 233b "checking that OBF of the FS .lustre succeeds"
20706
20707 test_234() {
20708         local p="$TMP/sanityN-$TESTNAME.parameters"
20709         save_lustre_params client "llite.*.xattr_cache" > $p
20710         lctl set_param llite.*.xattr_cache 1 ||
20711                 skip_env "xattr cache is not supported"
20712
20713         mkdir -p $DIR/$tdir || error "mkdir failed"
20714         touch $DIR/$tdir/$tfile || error "touch failed"
20715         # OBD_FAIL_LLITE_XATTR_ENOMEM
20716         $LCTL set_param fail_loc=0x1405
20717         getfattr -n user.attr $DIR/$tdir/$tfile &&
20718                 error "getfattr should have failed with ENOMEM"
20719         $LCTL set_param fail_loc=0x0
20720         rm -rf $DIR/$tdir
20721
20722         restore_lustre_params < $p
20723         rm -f $p
20724 }
20725 run_test 234 "xattr cache should not crash on ENOMEM"
20726
20727 test_235() {
20728         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20729                 skip "Need MDS version at least 2.4.52"
20730
20731         flock_deadlock $DIR/$tfile
20732         local RC=$?
20733         case $RC in
20734                 0)
20735                 ;;
20736                 124) error "process hangs on a deadlock"
20737                 ;;
20738                 *) error "error executing flock_deadlock $DIR/$tfile"
20739                 ;;
20740         esac
20741 }
20742 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20743
20744 #LU-2935
20745 test_236() {
20746         check_swap_layouts_support
20747
20748         local ref1=/etc/passwd
20749         local ref2=/etc/group
20750         local file1=$DIR/$tdir/f1
20751         local file2=$DIR/$tdir/f2
20752
20753         test_mkdir -c1 $DIR/$tdir
20754         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20755         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20756         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20757         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20758         local fd=$(free_fd)
20759         local cmd="exec $fd<>$file2"
20760         eval $cmd
20761         rm $file2
20762         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20763                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20764         cmd="exec $fd>&-"
20765         eval $cmd
20766         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20767
20768         #cleanup
20769         rm -rf $DIR/$tdir
20770 }
20771 run_test 236 "Layout swap on open unlinked file"
20772
20773 # LU-4659 linkea consistency
20774 test_238() {
20775         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20776                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20777                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20778                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20779
20780         touch $DIR/$tfile
20781         ln $DIR/$tfile $DIR/$tfile.lnk
20782         touch $DIR/$tfile.new
20783         mv $DIR/$tfile.new $DIR/$tfile
20784         local fid1=$($LFS path2fid $DIR/$tfile)
20785         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20786         local path1=$($LFS fid2path $FSNAME "$fid1")
20787         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20788         local path2=$($LFS fid2path $FSNAME "$fid2")
20789         [ $tfile.lnk == $path2 ] ||
20790                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20791         rm -f $DIR/$tfile*
20792 }
20793 run_test 238 "Verify linkea consistency"
20794
20795 test_239A() { # was test_239
20796         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20797                 skip "Need MDS version at least 2.5.60"
20798
20799         local list=$(comma_list $(mdts_nodes))
20800
20801         mkdir -p $DIR/$tdir
20802         createmany -o $DIR/$tdir/f- 5000
20803         unlinkmany $DIR/$tdir/f- 5000
20804         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20805                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20806         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20807                         osp.*MDT*.sync_in_flight" | calc_sum)
20808         [ "$changes" -eq 0 ] || error "$changes not synced"
20809 }
20810 run_test 239A "osp_sync test"
20811
20812 test_239a() { #LU-5297
20813         remote_mds_nodsh && skip "remote MDS with nodsh"
20814
20815         touch $DIR/$tfile
20816         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20817         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20818         chgrp $RUNAS_GID $DIR/$tfile
20819         wait_delete_completed
20820 }
20821 run_test 239a "process invalid osp sync record correctly"
20822
20823 test_239b() { #LU-5297
20824         remote_mds_nodsh && skip "remote MDS with nodsh"
20825
20826         touch $DIR/$tfile1
20827         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20828         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20829         chgrp $RUNAS_GID $DIR/$tfile1
20830         wait_delete_completed
20831         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20832         touch $DIR/$tfile2
20833         chgrp $RUNAS_GID $DIR/$tfile2
20834         wait_delete_completed
20835 }
20836 run_test 239b "process osp sync record with ENOMEM error correctly"
20837
20838 test_240() {
20839         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20840         remote_mds_nodsh && skip "remote MDS with nodsh"
20841
20842         mkdir -p $DIR/$tdir
20843
20844         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20845                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20846         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20847                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20848
20849         umount_client $MOUNT || error "umount failed"
20850         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20851         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20852         mount_client $MOUNT || error "failed to mount client"
20853
20854         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20855         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20856 }
20857 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20858
20859 test_241_bio() {
20860         local count=$1
20861         local bsize=$2
20862
20863         for LOOP in $(seq $count); do
20864                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20865                 cancel_lru_locks $OSC || true
20866         done
20867 }
20868
20869 test_241_dio() {
20870         local count=$1
20871         local bsize=$2
20872
20873         for LOOP in $(seq $1); do
20874                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20875                         2>/dev/null
20876         done
20877 }
20878
20879 test_241a() { # was test_241
20880         local bsize=$PAGE_SIZE
20881
20882         (( bsize < 40960 )) && bsize=40960
20883         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20884         ls -la $DIR/$tfile
20885         cancel_lru_locks $OSC
20886         test_241_bio 1000 $bsize &
20887         PID=$!
20888         test_241_dio 1000 $bsize
20889         wait $PID
20890 }
20891 run_test 241a "bio vs dio"
20892
20893 test_241b() {
20894         local bsize=$PAGE_SIZE
20895
20896         (( bsize < 40960 )) && bsize=40960
20897         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20898         ls -la $DIR/$tfile
20899         test_241_dio 1000 $bsize &
20900         PID=$!
20901         test_241_dio 1000 $bsize
20902         wait $PID
20903 }
20904 run_test 241b "dio vs dio"
20905
20906 test_242() {
20907         remote_mds_nodsh && skip "remote MDS with nodsh"
20908
20909         mkdir_on_mdt0 $DIR/$tdir
20910         touch $DIR/$tdir/$tfile
20911
20912         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20913         do_facet mds1 lctl set_param fail_loc=0x105
20914         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20915
20916         do_facet mds1 lctl set_param fail_loc=0
20917         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20918 }
20919 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20920
20921 test_243()
20922 {
20923         test_mkdir $DIR/$tdir
20924         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20925 }
20926 run_test 243 "various group lock tests"
20927
20928 test_244a()
20929 {
20930         test_mkdir $DIR/$tdir
20931         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20932         sendfile_grouplock $DIR/$tdir/$tfile || \
20933                 error "sendfile+grouplock failed"
20934         rm -rf $DIR/$tdir
20935 }
20936 run_test 244a "sendfile with group lock tests"
20937
20938 test_244b()
20939 {
20940         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20941
20942         local threads=50
20943         local size=$((1024*1024))
20944
20945         test_mkdir $DIR/$tdir
20946         for i in $(seq 1 $threads); do
20947                 local file=$DIR/$tdir/file_$((i / 10))
20948                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20949                 local pids[$i]=$!
20950         done
20951         for i in $(seq 1 $threads); do
20952                 wait ${pids[$i]}
20953         done
20954 }
20955 run_test 244b "multi-threaded write with group lock"
20956
20957 test_245a() {
20958         local flagname="multi_mod_rpcs"
20959         local connect_data_name="max_mod_rpcs"
20960         local out
20961
20962         # check if multiple modify RPCs flag is set
20963         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20964                 grep "connect_flags:")
20965         echo "$out"
20966
20967         echo "$out" | grep -qw $flagname
20968         if [ $? -ne 0 ]; then
20969                 echo "connect flag $flagname is not set"
20970                 return
20971         fi
20972
20973         # check if multiple modify RPCs data is set
20974         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20975         echo "$out"
20976
20977         echo "$out" | grep -qw $connect_data_name ||
20978                 error "import should have connect data $connect_data_name"
20979 }
20980 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
20981
20982 test_245b() {
20983         local flagname="multi_mod_rpcs"
20984         local connect_data_name="max_mod_rpcs"
20985         local out
20986
20987         remote_mds_nodsh && skip "remote MDS with nodsh" && return
20988         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
20989
20990         # check if multiple modify RPCs flag is set
20991         out=$(do_facet mds1 \
20992                 $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
20993                 grep "connect_flags:")
20994         echo "$out"
20995
20996         if [[ "$out" =~ $flagname ]]; then
20997                 echo "connect flag $flagname is not set"
20998                 return 0
20999         fi
21000
21001         # check if multiple modify RPCs data is set
21002         out=$(do_facet mds1 \
21003                 $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21004
21005         [[ "$out" =~ $connect_data_name ]] ||
21006                 error "import should have connect data $connect_data_name"
21007 }
21008 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21009
21010 cleanup_247() {
21011         local submount=$1
21012
21013         trap 0
21014         umount_client $submount
21015         rmdir $submount
21016 }
21017
21018 test_247a() {
21019         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21020                 grep -q subtree ||
21021                 skip_env "Fileset feature is not supported"
21022
21023         local submount=${MOUNT}_$tdir
21024
21025         mkdir $MOUNT/$tdir
21026         mkdir -p $submount || error "mkdir $submount failed"
21027         FILESET="$FILESET/$tdir" mount_client $submount ||
21028                 error "mount $submount failed"
21029         trap "cleanup_247 $submount" EXIT
21030         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21031         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21032                 error "read $MOUNT/$tdir/$tfile failed"
21033         cleanup_247 $submount
21034 }
21035 run_test 247a "mount subdir as fileset"
21036
21037 test_247b() {
21038         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21039                 skip_env "Fileset feature is not supported"
21040
21041         local submount=${MOUNT}_$tdir
21042
21043         rm -rf $MOUNT/$tdir
21044         mkdir -p $submount || error "mkdir $submount failed"
21045         SKIP_FILESET=1
21046         FILESET="$FILESET/$tdir" mount_client $submount &&
21047                 error "mount $submount should fail"
21048         rmdir $submount
21049 }
21050 run_test 247b "mount subdir that dose not exist"
21051
21052 test_247c() {
21053         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21054                 skip_env "Fileset feature is not supported"
21055
21056         local submount=${MOUNT}_$tdir
21057
21058         mkdir -p $MOUNT/$tdir/dir1
21059         mkdir -p $submount || error "mkdir $submount failed"
21060         trap "cleanup_247 $submount" EXIT
21061         FILESET="$FILESET/$tdir" mount_client $submount ||
21062                 error "mount $submount failed"
21063         local fid=$($LFS path2fid $MOUNT/)
21064         $LFS fid2path $submount $fid && error "fid2path should fail"
21065         cleanup_247 $submount
21066 }
21067 run_test 247c "running fid2path outside subdirectory root"
21068
21069 test_247d() {
21070         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21071                 skip "Fileset feature is not supported"
21072
21073         local submount=${MOUNT}_$tdir
21074
21075         mkdir -p $MOUNT/$tdir/dir1
21076         mkdir -p $submount || error "mkdir $submount failed"
21077         FILESET="$FILESET/$tdir" mount_client $submount ||
21078                 error "mount $submount failed"
21079         trap "cleanup_247 $submount" EXIT
21080
21081         local td=$submount/dir1
21082         local fid=$($LFS path2fid $td)
21083         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21084
21085         # check that we get the same pathname back
21086         local rootpath
21087         local found
21088         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21089                 echo "$rootpath $fid"
21090                 found=$($LFS fid2path $rootpath "$fid")
21091                 [ -n "$found" ] || error "fid2path should succeed"
21092                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21093         done
21094         # check wrong root path format
21095         rootpath=$submount"_wrong"
21096         found=$($LFS fid2path $rootpath "$fid")
21097         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21098
21099         cleanup_247 $submount
21100 }
21101 run_test 247d "running fid2path inside subdirectory root"
21102
21103 # LU-8037
21104 test_247e() {
21105         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21106                 grep -q subtree ||
21107                 skip "Fileset feature is not supported"
21108
21109         local submount=${MOUNT}_$tdir
21110
21111         mkdir $MOUNT/$tdir
21112         mkdir -p $submount || error "mkdir $submount failed"
21113         FILESET="$FILESET/.." mount_client $submount &&
21114                 error "mount $submount should fail"
21115         rmdir $submount
21116 }
21117 run_test 247e "mount .. as fileset"
21118
21119 test_247f() {
21120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21121         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21122                 skip "Need at least version 2.13.52"
21123         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21124                 skip "Need at least version 2.14.50"
21125         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21126                 grep -q subtree ||
21127                 skip "Fileset feature is not supported"
21128
21129         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21130         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21131                 error "mkdir remote failed"
21132         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21133                 error "mkdir remote/subdir failed"
21134         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21135                 error "mkdir striped failed"
21136         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21137
21138         local submount=${MOUNT}_$tdir
21139
21140         mkdir -p $submount || error "mkdir $submount failed"
21141         stack_trap "rmdir $submount"
21142
21143         local dir
21144         local stat
21145         local fileset=$FILESET
21146         local mdts=$(comma_list $(mdts_nodes))
21147
21148         stat=$(do_facet mds1 $LCTL get_param -n \
21149                 mdt.*MDT0000.enable_remote_subdir_mount)
21150         stack_trap "do_nodes $mdts $LCTL set_param \
21151                 mdt.*.enable_remote_subdir_mount=$stat"
21152
21153         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21154         stack_trap "umount_client $submount"
21155         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21156                 error "mount remote dir $dir should fail"
21157
21158         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21159                 $tdir/striped/. ; do
21160                 FILESET="$fileset/$dir" mount_client $submount ||
21161                         error "mount $dir failed"
21162                 umount_client $submount
21163         done
21164
21165         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21166         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21167                 error "mount $tdir/remote failed"
21168 }
21169 run_test 247f "mount striped or remote directory as fileset"
21170
21171 test_247g() {
21172         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21173         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21174                 skip "Need at least version 2.14.50"
21175
21176         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21177                 error "mkdir $tdir failed"
21178         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21179
21180         local submount=${MOUNT}_$tdir
21181
21182         mkdir -p $submount || error "mkdir $submount failed"
21183         stack_trap "rmdir $submount"
21184
21185         FILESET="$fileset/$tdir" mount_client $submount ||
21186                 error "mount $dir failed"
21187         stack_trap "umount $submount"
21188
21189         local mdts=$(comma_list $(mdts_nodes))
21190
21191         local nrpcs
21192
21193         stat $submount > /dev/null
21194         cancel_lru_locks $MDC
21195         stat $submount > /dev/null
21196         stat $submount/$tfile > /dev/null
21197         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21198         stat $submount/$tfile > /dev/null
21199         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21200                 awk '/getattr/ {sum += $2} END {print sum}')
21201
21202         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21203 }
21204 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21205
21206 test_248a() {
21207         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21208         [ -z "$fast_read_sav" ] && skip "no fast read support"
21209
21210         # create a large file for fast read verification
21211         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21212
21213         # make sure the file is created correctly
21214         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21215                 { rm -f $DIR/$tfile; skip "file creation error"; }
21216
21217         echo "Test 1: verify that fast read is 4 times faster on cache read"
21218
21219         # small read with fast read enabled
21220         $LCTL set_param -n llite.*.fast_read=1
21221         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21222                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21223                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21224         # small read with fast read disabled
21225         $LCTL set_param -n llite.*.fast_read=0
21226         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21227                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21228                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21229
21230         # verify that fast read is 4 times faster for cache read
21231         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21232                 error_not_in_vm "fast read was not 4 times faster: " \
21233                            "$t_fast vs $t_slow"
21234
21235         echo "Test 2: verify the performance between big and small read"
21236         $LCTL set_param -n llite.*.fast_read=1
21237
21238         # 1k non-cache read
21239         cancel_lru_locks osc
21240         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21241                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21242                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21243
21244         # 1M non-cache read
21245         cancel_lru_locks osc
21246         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21247                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21248                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21249
21250         # verify that big IO is not 4 times faster than small IO
21251         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21252                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21253
21254         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21255         rm -f $DIR/$tfile
21256 }
21257 run_test 248a "fast read verification"
21258
21259 test_248b() {
21260         # Default short_io_bytes=16384, try both smaller and larger sizes.
21261         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21262         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21263         echo "bs=53248 count=113 normal buffered write"
21264         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21265                 error "dd of initial data file failed"
21266         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21267
21268         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21269         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21270                 error "dd with sync normal writes failed"
21271         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21272
21273         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21274         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21275                 error "dd with sync small writes failed"
21276         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21277
21278         cancel_lru_locks osc
21279
21280         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21281         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21282         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21283         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21284                 iflag=direct || error "dd with O_DIRECT small read failed"
21285         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21286         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21287                 error "compare $TMP/$tfile.1 failed"
21288
21289         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21290         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21291
21292         # just to see what the maximum tunable value is, and test parsing
21293         echo "test invalid parameter 2MB"
21294         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21295                 error "too-large short_io_bytes allowed"
21296         echo "test maximum parameter 512KB"
21297         # if we can set a larger short_io_bytes, run test regardless of version
21298         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21299                 # older clients may not allow setting it this large, that's OK
21300                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21301                         skip "Need at least client version 2.13.50"
21302                 error "medium short_io_bytes failed"
21303         fi
21304         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21305         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21306
21307         echo "test large parameter 64KB"
21308         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21309         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21310
21311         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21312         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21313                 error "dd with sync large writes failed"
21314         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21315
21316         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21317         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21318         num=$((113 * 4096 / PAGE_SIZE))
21319         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21320         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21321                 error "dd with O_DIRECT large writes failed"
21322         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21323                 error "compare $DIR/$tfile.3 failed"
21324
21325         cancel_lru_locks osc
21326
21327         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21328         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21329                 error "dd with O_DIRECT large read failed"
21330         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21331                 error "compare $TMP/$tfile.2 failed"
21332
21333         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21334         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21335                 error "dd with O_DIRECT large read failed"
21336         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21337                 error "compare $TMP/$tfile.3 failed"
21338 }
21339 run_test 248b "test short_io read and write for both small and large sizes"
21340
21341 test_249() { # LU-7890
21342         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21343                 skip "Need at least version 2.8.54"
21344
21345         rm -f $DIR/$tfile
21346         $LFS setstripe -c 1 $DIR/$tfile
21347         # Offset 2T == 4k * 512M
21348         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21349                 error "dd to 2T offset failed"
21350 }
21351 run_test 249 "Write above 2T file size"
21352
21353 test_250() {
21354         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21355          && skip "no 16TB file size limit on ZFS"
21356
21357         $LFS setstripe -c 1 $DIR/$tfile
21358         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21359         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21360         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21361         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21362                 conv=notrunc,fsync && error "append succeeded"
21363         return 0
21364 }
21365 run_test 250 "Write above 16T limit"
21366
21367 test_251() {
21368         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21369
21370         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21371         #Skip once - writing the first stripe will succeed
21372         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21373         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21374                 error "short write happened"
21375
21376         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21377         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21378                 error "short read happened"
21379
21380         rm -f $DIR/$tfile
21381 }
21382 run_test 251 "Handling short read and write correctly"
21383
21384 test_252() {
21385         remote_mds_nodsh && skip "remote MDS with nodsh"
21386         remote_ost_nodsh && skip "remote OST with nodsh"
21387         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21388                 skip_env "ldiskfs only test"
21389         fi
21390
21391         local tgt
21392         local dev
21393         local out
21394         local uuid
21395         local num
21396         local gen
21397
21398         # check lr_reader on OST0000
21399         tgt=ost1
21400         dev=$(facet_device $tgt)
21401         out=$(do_facet $tgt $LR_READER $dev)
21402         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21403         echo "$out"
21404         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21405         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21406                 error "Invalid uuid returned by $LR_READER on target $tgt"
21407         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21408
21409         # check lr_reader -c on MDT0000
21410         tgt=mds1
21411         dev=$(facet_device $tgt)
21412         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21413                 skip "$LR_READER does not support additional options"
21414         fi
21415         out=$(do_facet $tgt $LR_READER -c $dev)
21416         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21417         echo "$out"
21418         num=$(echo "$out" | grep -c "mdtlov")
21419         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21420                 error "Invalid number of mdtlov clients returned by $LR_READER"
21421         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21422
21423         # check lr_reader -cr on MDT0000
21424         out=$(do_facet $tgt $LR_READER -cr $dev)
21425         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21426         echo "$out"
21427         echo "$out" | grep -q "^reply_data:$" ||
21428                 error "$LR_READER should have returned 'reply_data' section"
21429         num=$(echo "$out" | grep -c "client_generation")
21430         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21431 }
21432 run_test 252 "check lr_reader tool"
21433
21434 test_253() {
21435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21436         remote_mds_nodsh && skip "remote MDS with nodsh"
21437         remote_mgs_nodsh && skip "remote MGS with nodsh"
21438
21439         local ostidx=0
21440         local rc=0
21441         local ost_name=$(ostname_from_index $ostidx)
21442
21443         # on the mdt's osc
21444         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21445         do_facet $SINGLEMDS $LCTL get_param -n \
21446                 osp.$mdtosc_proc1.reserved_mb_high ||
21447                 skip  "remote MDS does not support reserved_mb_high"
21448
21449         rm -rf $DIR/$tdir
21450         wait_mds_ost_sync
21451         wait_delete_completed
21452         mkdir $DIR/$tdir
21453
21454         pool_add $TESTNAME || error "Pool creation failed"
21455         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21456
21457         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21458                 error "Setstripe failed"
21459
21460         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21461
21462         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21463                     grep "watermarks")
21464         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21465
21466         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21467                         osp.$mdtosc_proc1.prealloc_status)
21468         echo "prealloc_status $oa_status"
21469
21470         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21471                 error "File creation should fail"
21472
21473         #object allocation was stopped, but we still able to append files
21474         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21475                 oflag=append || error "Append failed"
21476
21477         rm -f $DIR/$tdir/$tfile.0
21478
21479         # For this test, we want to delete the files we created to go out of
21480         # space but leave the watermark, so we remain nearly out of space
21481         ost_watermarks_enospc_delete_files $tfile $ostidx
21482
21483         wait_delete_completed
21484
21485         sleep_maxage
21486
21487         for i in $(seq 10 12); do
21488                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21489                         2>/dev/null || error "File creation failed after rm"
21490         done
21491
21492         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21493                         osp.$mdtosc_proc1.prealloc_status)
21494         echo "prealloc_status $oa_status"
21495
21496         if (( oa_status != 0 )); then
21497                 error "Object allocation still disable after rm"
21498         fi
21499 }
21500 run_test 253 "Check object allocation limit"
21501
21502 test_254() {
21503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21504         remote_mds_nodsh && skip "remote MDS with nodsh"
21505
21506         local mdt=$(facet_svc $SINGLEMDS)
21507
21508         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21509                 skip "MDS does not support changelog_size"
21510
21511         local cl_user
21512
21513         changelog_register || error "changelog_register failed"
21514
21515         changelog_clear 0 || error "changelog_clear failed"
21516
21517         local size1=$(do_facet $SINGLEMDS \
21518                       $LCTL get_param -n mdd.$mdt.changelog_size)
21519         echo "Changelog size $size1"
21520
21521         rm -rf $DIR/$tdir
21522         $LFS mkdir -i 0 $DIR/$tdir
21523         # change something
21524         mkdir -p $DIR/$tdir/pics/2008/zachy
21525         touch $DIR/$tdir/pics/2008/zachy/timestamp
21526         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21527         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21528         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21529         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21530         rm $DIR/$tdir/pics/desktop.jpg
21531
21532         local size2=$(do_facet $SINGLEMDS \
21533                       $LCTL get_param -n mdd.$mdt.changelog_size)
21534         echo "Changelog size after work $size2"
21535
21536         (( $size2 > $size1 )) ||
21537                 error "new Changelog size=$size2 less than old size=$size1"
21538 }
21539 run_test 254 "Check changelog size"
21540
21541 ladvise_no_type()
21542 {
21543         local type=$1
21544         local file=$2
21545
21546         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21547                 awk -F: '{print $2}' | grep $type > /dev/null
21548         if [ $? -ne 0 ]; then
21549                 return 0
21550         fi
21551         return 1
21552 }
21553
21554 ladvise_no_ioctl()
21555 {
21556         local file=$1
21557
21558         lfs ladvise -a willread $file > /dev/null 2>&1
21559         if [ $? -eq 0 ]; then
21560                 return 1
21561         fi
21562
21563         lfs ladvise -a willread $file 2>&1 |
21564                 grep "Inappropriate ioctl for device" > /dev/null
21565         if [ $? -eq 0 ]; then
21566                 return 0
21567         fi
21568         return 1
21569 }
21570
21571 percent() {
21572         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21573 }
21574
21575 # run a random read IO workload
21576 # usage: random_read_iops <filename> <filesize> <iosize>
21577 random_read_iops() {
21578         local file=$1
21579         local fsize=$2
21580         local iosize=${3:-4096}
21581
21582         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21583                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21584 }
21585
21586 drop_file_oss_cache() {
21587         local file="$1"
21588         local nodes="$2"
21589
21590         $LFS ladvise -a dontneed $file 2>/dev/null ||
21591                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21592 }
21593
21594 ladvise_willread_performance()
21595 {
21596         local repeat=10
21597         local average_origin=0
21598         local average_cache=0
21599         local average_ladvise=0
21600
21601         for ((i = 1; i <= $repeat; i++)); do
21602                 echo "Iter $i/$repeat: reading without willread hint"
21603                 cancel_lru_locks osc
21604                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21605                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21606                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21607                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21608
21609                 cancel_lru_locks osc
21610                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21611                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21612                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21613
21614                 cancel_lru_locks osc
21615                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21616                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21617                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21618                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21619                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21620         done
21621         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21622         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21623         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21624
21625         speedup_cache=$(percent $average_cache $average_origin)
21626         speedup_ladvise=$(percent $average_ladvise $average_origin)
21627
21628         echo "Average uncached read: $average_origin"
21629         echo "Average speedup with OSS cached read: " \
21630                 "$average_cache = +$speedup_cache%"
21631         echo "Average speedup with ladvise willread: " \
21632                 "$average_ladvise = +$speedup_ladvise%"
21633
21634         local lowest_speedup=20
21635         if (( ${average_cache%.*} < $lowest_speedup )); then
21636                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
21637                      " got $average_cache%. Skipping ladvise willread check."
21638                 return 0
21639         fi
21640
21641         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21642         # it is still good to run until then to exercise 'ladvise willread'
21643         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21644                 [ "$ost1_FSTYPE" = "zfs" ] &&
21645                 echo "osd-zfs does not support dontneed or drop_caches" &&
21646                 return 0
21647
21648         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21649         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
21650                 error_not_in_vm "Speedup with willread is less than " \
21651                         "$lowest_speedup%, got $average_ladvise%"
21652 }
21653
21654 test_255a() {
21655         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21656                 skip "lustre < 2.8.54 does not support ladvise "
21657         remote_ost_nodsh && skip "remote OST with nodsh"
21658
21659         stack_trap "rm -f $DIR/$tfile"
21660         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21661
21662         ladvise_no_type willread $DIR/$tfile &&
21663                 skip "willread ladvise is not supported"
21664
21665         ladvise_no_ioctl $DIR/$tfile &&
21666                 skip "ladvise ioctl is not supported"
21667
21668         local size_mb=100
21669         local size=$((size_mb * 1048576))
21670         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21671                 error "dd to $DIR/$tfile failed"
21672
21673         lfs ladvise -a willread $DIR/$tfile ||
21674                 error "Ladvise failed with no range argument"
21675
21676         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21677                 error "Ladvise failed with no -l or -e argument"
21678
21679         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21680                 error "Ladvise failed with only -e argument"
21681
21682         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21683                 error "Ladvise failed with only -l argument"
21684
21685         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21686                 error "End offset should not be smaller than start offset"
21687
21688         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21689                 error "End offset should not be equal to start offset"
21690
21691         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21692                 error "Ladvise failed with overflowing -s argument"
21693
21694         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21695                 error "Ladvise failed with overflowing -e argument"
21696
21697         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21698                 error "Ladvise failed with overflowing -l argument"
21699
21700         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21701                 error "Ladvise succeeded with conflicting -l and -e arguments"
21702
21703         echo "Synchronous ladvise should wait"
21704         local delay=4
21705 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21706         do_nodes $(comma_list $(osts_nodes)) \
21707                 $LCTL set_param fail_val=$delay fail_loc=0x237
21708
21709         local start_ts=$SECONDS
21710         lfs ladvise -a willread $DIR/$tfile ||
21711                 error "Ladvise failed with no range argument"
21712         local end_ts=$SECONDS
21713         local inteval_ts=$((end_ts - start_ts))
21714
21715         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21716                 error "Synchronous advice didn't wait reply"
21717         fi
21718
21719         echo "Asynchronous ladvise shouldn't wait"
21720         local start_ts=$SECONDS
21721         lfs ladvise -a willread -b $DIR/$tfile ||
21722                 error "Ladvise failed with no range argument"
21723         local end_ts=$SECONDS
21724         local inteval_ts=$((end_ts - start_ts))
21725
21726         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21727                 error "Asynchronous advice blocked"
21728         fi
21729
21730         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21731         ladvise_willread_performance
21732 }
21733 run_test 255a "check 'lfs ladvise -a willread'"
21734
21735 facet_meminfo() {
21736         local facet=$1
21737         local info=$2
21738
21739         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21740 }
21741
21742 test_255b() {
21743         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21744                 skip "lustre < 2.8.54 does not support ladvise "
21745         remote_ost_nodsh && skip "remote OST with nodsh"
21746
21747         stack_trap "rm -f $DIR/$tfile"
21748         lfs setstripe -c 1 -i 0 $DIR/$tfile
21749
21750         ladvise_no_type dontneed $DIR/$tfile &&
21751                 skip "dontneed ladvise is not supported"
21752
21753         ladvise_no_ioctl $DIR/$tfile &&
21754                 skip "ladvise ioctl is not supported"
21755
21756         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21757                 [ "$ost1_FSTYPE" = "zfs" ] &&
21758                 skip "zfs-osd does not support 'ladvise dontneed'"
21759
21760         local size_mb=100
21761         local size=$((size_mb * 1048576))
21762         # In order to prevent disturbance of other processes, only check 3/4
21763         # of the memory usage
21764         local kibibytes=$((size_mb * 1024 * 3 / 4))
21765
21766         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21767                 error "dd to $DIR/$tfile failed"
21768
21769         #force write to complete before dropping OST cache & checking memory
21770         sync
21771
21772         local total=$(facet_meminfo ost1 MemTotal)
21773         echo "Total memory: $total KiB"
21774
21775         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21776         local before_read=$(facet_meminfo ost1 Cached)
21777         echo "Cache used before read: $before_read KiB"
21778
21779         lfs ladvise -a willread $DIR/$tfile ||
21780                 error "Ladvise willread failed"
21781         local after_read=$(facet_meminfo ost1 Cached)
21782         echo "Cache used after read: $after_read KiB"
21783
21784         lfs ladvise -a dontneed $DIR/$tfile ||
21785                 error "Ladvise dontneed again failed"
21786         local no_read=$(facet_meminfo ost1 Cached)
21787         echo "Cache used after dontneed ladvise: $no_read KiB"
21788
21789         if [ $total -lt $((before_read + kibibytes)) ]; then
21790                 echo "Memory is too small, abort checking"
21791                 return 0
21792         fi
21793
21794         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21795                 error "Ladvise willread should use more memory" \
21796                         "than $kibibytes KiB"
21797         fi
21798
21799         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21800                 error "Ladvise dontneed should release more memory" \
21801                         "than $kibibytes KiB"
21802         fi
21803 }
21804 run_test 255b "check 'lfs ladvise -a dontneed'"
21805
21806 test_255c() {
21807         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21808                 skip "lustre < 2.10.50 does not support lockahead"
21809
21810         local ost1_imp=$(get_osc_import_name client ost1)
21811         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21812                          cut -d'.' -f2)
21813         local count
21814         local new_count
21815         local difference
21816         local i
21817         local rc
21818
21819         test_mkdir -p $DIR/$tdir
21820         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21821
21822         #test 10 returns only success/failure
21823         i=10
21824         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21825         rc=$?
21826         if [ $rc -eq 255 ]; then
21827                 error "Ladvise test${i} failed, ${rc}"
21828         fi
21829
21830         #test 11 counts lock enqueue requests, all others count new locks
21831         i=11
21832         count=$(do_facet ost1 \
21833                 $LCTL get_param -n ost.OSS.ost.stats)
21834         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21835
21836         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21837         rc=$?
21838         if [ $rc -eq 255 ]; then
21839                 error "Ladvise test${i} failed, ${rc}"
21840         fi
21841
21842         new_count=$(do_facet ost1 \
21843                 $LCTL get_param -n ost.OSS.ost.stats)
21844         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21845                    awk '{ print $2 }')
21846
21847         difference="$((new_count - count))"
21848         if [ $difference -ne $rc ]; then
21849                 error "Ladvise test${i}, bad enqueue count, returned " \
21850                       "${rc}, actual ${difference}"
21851         fi
21852
21853         for i in $(seq 12 21); do
21854                 # If we do not do this, we run the risk of having too many
21855                 # locks and starting lock cancellation while we are checking
21856                 # lock counts.
21857                 cancel_lru_locks osc
21858
21859                 count=$($LCTL get_param -n \
21860                        ldlm.namespaces.$imp_name.lock_unused_count)
21861
21862                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21863                 rc=$?
21864                 if [ $rc -eq 255 ]; then
21865                         error "Ladvise test ${i} failed, ${rc}"
21866                 fi
21867
21868                 new_count=$($LCTL get_param -n \
21869                        ldlm.namespaces.$imp_name.lock_unused_count)
21870                 difference="$((new_count - count))"
21871
21872                 # Test 15 output is divided by 100 to map down to valid return
21873                 if [ $i -eq 15 ]; then
21874                         rc="$((rc * 100))"
21875                 fi
21876
21877                 if [ $difference -ne $rc ]; then
21878                         error "Ladvise test ${i}, bad lock count, returned " \
21879                               "${rc}, actual ${difference}"
21880                 fi
21881         done
21882
21883         #test 22 returns only success/failure
21884         i=22
21885         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21886         rc=$?
21887         if [ $rc -eq 255 ]; then
21888                 error "Ladvise test${i} failed, ${rc}"
21889         fi
21890 }
21891 run_test 255c "suite of ladvise lockahead tests"
21892
21893 test_256() {
21894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21895         remote_mds_nodsh && skip "remote MDS with nodsh"
21896         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21897         changelog_users $SINGLEMDS | grep "^cl" &&
21898                 skip "active changelog user"
21899
21900         local cl_user
21901         local cat_sl
21902         local mdt_dev
21903
21904         mdt_dev=$(facet_device $SINGLEMDS)
21905         echo $mdt_dev
21906
21907         changelog_register || error "changelog_register failed"
21908
21909         rm -rf $DIR/$tdir
21910         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
21911
21912         changelog_clear 0 || error "changelog_clear failed"
21913
21914         # change something
21915         touch $DIR/$tdir/{1..10}
21916
21917         # stop the MDT
21918         stop $SINGLEMDS || error "Fail to stop MDT"
21919
21920         # remount the MDT
21921         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21922                 error "Fail to start MDT"
21923
21924         #after mount new plainllog is used
21925         touch $DIR/$tdir/{11..19}
21926         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21927         stack_trap "rm -f $tmpfile"
21928         cat_sl=$(do_facet $SINGLEMDS "sync; \
21929                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21930                  llog_reader $tmpfile | grep -c type=1064553b")
21931         do_facet $SINGLEMDS llog_reader $tmpfile
21932
21933         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21934
21935         changelog_clear 0 || error "changelog_clear failed"
21936
21937         cat_sl=$(do_facet $SINGLEMDS "sync; \
21938                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21939                  llog_reader $tmpfile | grep -c type=1064553b")
21940
21941         if (( cat_sl == 2 )); then
21942                 error "Empty plain llog was not deleted from changelog catalog"
21943         elif (( cat_sl != 1 )); then
21944                 error "Active plain llog shouldn't be deleted from catalog"
21945         fi
21946 }
21947 run_test 256 "Check llog delete for empty and not full state"
21948
21949 test_257() {
21950         remote_mds_nodsh && skip "remote MDS with nodsh"
21951         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21952                 skip "Need MDS version at least 2.8.55"
21953
21954         test_mkdir $DIR/$tdir
21955
21956         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21957                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21958         stat $DIR/$tdir
21959
21960 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21961         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21962         local facet=mds$((mdtidx + 1))
21963         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21964         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21965
21966         stop $facet || error "stop MDS failed"
21967         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21968                 error "start MDS fail"
21969         wait_recovery_complete $facet
21970 }
21971 run_test 257 "xattr locks are not lost"
21972
21973 # Verify we take the i_mutex when security requires it
21974 test_258a() {
21975 #define OBD_FAIL_IMUTEX_SEC 0x141c
21976         $LCTL set_param fail_loc=0x141c
21977         touch $DIR/$tfile
21978         chmod u+s $DIR/$tfile
21979         chmod a+rwx $DIR/$tfile
21980         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21981         RC=$?
21982         if [ $RC -ne 0 ]; then
21983                 error "error, failed to take i_mutex, rc=$?"
21984         fi
21985         rm -f $DIR/$tfile
21986 }
21987 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21988
21989 # Verify we do NOT take the i_mutex in the normal case
21990 test_258b() {
21991 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21992         $LCTL set_param fail_loc=0x141d
21993         touch $DIR/$tfile
21994         chmod a+rwx $DIR
21995         chmod a+rw $DIR/$tfile
21996         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21997         RC=$?
21998         if [ $RC -ne 0 ]; then
21999                 error "error, took i_mutex unnecessarily, rc=$?"
22000         fi
22001         rm -f $DIR/$tfile
22002
22003 }
22004 run_test 258b "verify i_mutex security behavior"
22005
22006 test_259() {
22007         local file=$DIR/$tfile
22008         local before
22009         local after
22010
22011         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22012
22013         stack_trap "rm -f $file" EXIT
22014
22015         wait_delete_completed
22016         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22017         echo "before: $before"
22018
22019         $LFS setstripe -i 0 -c 1 $file
22020         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22021         sync_all_data
22022         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22023         echo "after write: $after"
22024
22025 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22026         do_facet ost1 $LCTL set_param fail_loc=0x2301
22027         $TRUNCATE $file 0
22028         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22029         echo "after truncate: $after"
22030
22031         stop ost1
22032         do_facet ost1 $LCTL set_param fail_loc=0
22033         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22034         sleep 2
22035         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22036         echo "after restart: $after"
22037         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22038                 error "missing truncate?"
22039
22040         return 0
22041 }
22042 run_test 259 "crash at delayed truncate"
22043
22044 test_260() {
22045 #define OBD_FAIL_MDC_CLOSE               0x806
22046         $LCTL set_param fail_loc=0x80000806
22047         touch $DIR/$tfile
22048
22049 }
22050 run_test 260 "Check mdc_close fail"
22051
22052 ### Data-on-MDT sanity tests ###
22053 test_270a() {
22054         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22055                 skip "Need MDS version at least 2.10.55 for DoM"
22056
22057         # create DoM file
22058         local dom=$DIR/$tdir/dom_file
22059         local tmp=$DIR/$tdir/tmp_file
22060
22061         mkdir_on_mdt0 $DIR/$tdir
22062
22063         # basic checks for DoM component creation
22064         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22065                 error "Can set MDT layout to non-first entry"
22066
22067         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22068                 error "Can define multiple entries as MDT layout"
22069
22070         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22071
22072         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22073         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22074         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22075
22076         local mdtidx=$($LFS getstripe -m $dom)
22077         local mdtname=MDT$(printf %04x $mdtidx)
22078         local facet=mds$((mdtidx + 1))
22079         local space_check=1
22080
22081         # Skip free space checks with ZFS
22082         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22083
22084         # write
22085         sync
22086         local size_tmp=$((65536 * 3))
22087         local mdtfree1=$(do_facet $facet \
22088                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22089
22090         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22091         # check also direct IO along write
22092         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22093         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22094         sync
22095         cmp $tmp $dom || error "file data is different"
22096         [ $(stat -c%s $dom) == $size_tmp ] ||
22097                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22098         if [ $space_check == 1 ]; then
22099                 local mdtfree2=$(do_facet $facet \
22100                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22101
22102                 # increase in usage from by $size_tmp
22103                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22104                         error "MDT free space wrong after write: " \
22105                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22106         fi
22107
22108         # truncate
22109         local size_dom=10000
22110
22111         $TRUNCATE $dom $size_dom
22112         [ $(stat -c%s $dom) == $size_dom ] ||
22113                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22114         if [ $space_check == 1 ]; then
22115                 mdtfree1=$(do_facet $facet \
22116                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22117                 # decrease in usage from $size_tmp to new $size_dom
22118                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22119                   $(((size_tmp - size_dom) / 1024)) ] ||
22120                         error "MDT free space is wrong after truncate: " \
22121                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22122         fi
22123
22124         # append
22125         cat $tmp >> $dom
22126         sync
22127         size_dom=$((size_dom + size_tmp))
22128         [ $(stat -c%s $dom) == $size_dom ] ||
22129                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22130         if [ $space_check == 1 ]; then
22131                 mdtfree2=$(do_facet $facet \
22132                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22133                 # increase in usage by $size_tmp from previous
22134                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22135                         error "MDT free space is wrong after append: " \
22136                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22137         fi
22138
22139         # delete
22140         rm $dom
22141         if [ $space_check == 1 ]; then
22142                 mdtfree1=$(do_facet $facet \
22143                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22144                 # decrease in usage by $size_dom from previous
22145                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22146                         error "MDT free space is wrong after removal: " \
22147                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22148         fi
22149
22150         # combined striping
22151         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22152                 error "Can't create DoM + OST striping"
22153
22154         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22155         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22156         # check also direct IO along write
22157         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22158         sync
22159         cmp $tmp $dom || error "file data is different"
22160         [ $(stat -c%s $dom) == $size_tmp ] ||
22161                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22162         rm $dom $tmp
22163
22164         return 0
22165 }
22166 run_test 270a "DoM: basic functionality tests"
22167
22168 test_270b() {
22169         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22170                 skip "Need MDS version at least 2.10.55"
22171
22172         local dom=$DIR/$tdir/dom_file
22173         local max_size=1048576
22174
22175         mkdir -p $DIR/$tdir
22176         $LFS setstripe -E $max_size -L mdt $dom
22177
22178         # truncate over the limit
22179         $TRUNCATE $dom $(($max_size + 1)) &&
22180                 error "successful truncate over the maximum size"
22181         # write over the limit
22182         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22183                 error "successful write over the maximum size"
22184         # append over the limit
22185         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22186         echo "12345" >> $dom && error "successful append over the maximum size"
22187         rm $dom
22188
22189         return 0
22190 }
22191 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22192
22193 test_270c() {
22194         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22195                 skip "Need MDS version at least 2.10.55"
22196
22197         mkdir -p $DIR/$tdir
22198         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22199
22200         # check files inherit DoM EA
22201         touch $DIR/$tdir/first
22202         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22203                 error "bad pattern"
22204         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22205                 error "bad stripe count"
22206         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22207                 error "bad stripe size"
22208
22209         # check directory inherits DoM EA and uses it as default
22210         mkdir $DIR/$tdir/subdir
22211         touch $DIR/$tdir/subdir/second
22212         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22213                 error "bad pattern in sub-directory"
22214         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22215                 error "bad stripe count in sub-directory"
22216         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22217                 error "bad stripe size in sub-directory"
22218         return 0
22219 }
22220 run_test 270c "DoM: DoM EA inheritance tests"
22221
22222 test_270d() {
22223         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22224                 skip "Need MDS version at least 2.10.55"
22225
22226         mkdir -p $DIR/$tdir
22227         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22228
22229         # inherit default DoM striping
22230         mkdir $DIR/$tdir/subdir
22231         touch $DIR/$tdir/subdir/f1
22232
22233         # change default directory striping
22234         $LFS setstripe -c 1 $DIR/$tdir/subdir
22235         touch $DIR/$tdir/subdir/f2
22236         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22237                 error "wrong default striping in file 2"
22238         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22239                 error "bad pattern in file 2"
22240         return 0
22241 }
22242 run_test 270d "DoM: change striping from DoM to RAID0"
22243
22244 test_270e() {
22245         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22246                 skip "Need MDS version at least 2.10.55"
22247
22248         mkdir -p $DIR/$tdir/dom
22249         mkdir -p $DIR/$tdir/norm
22250         DOMFILES=20
22251         NORMFILES=10
22252         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22253         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22254
22255         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22256         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22257
22258         # find DoM files by layout
22259         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22260         [ $NUM -eq  $DOMFILES ] ||
22261                 error "lfs find -L: found $NUM, expected $DOMFILES"
22262         echo "Test 1: lfs find 20 DOM files by layout: OK"
22263
22264         # there should be 1 dir with default DOM striping
22265         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22266         [ $NUM -eq  1 ] ||
22267                 error "lfs find -L: found $NUM, expected 1 dir"
22268         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22269
22270         # find DoM files by stripe size
22271         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22272         [ $NUM -eq  $DOMFILES ] ||
22273                 error "lfs find -S: found $NUM, expected $DOMFILES"
22274         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22275
22276         # find files by stripe offset except DoM files
22277         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22278         [ $NUM -eq  $NORMFILES ] ||
22279                 error "lfs find -i: found $NUM, expected $NORMFILES"
22280         echo "Test 5: lfs find no DOM files by stripe index: OK"
22281         return 0
22282 }
22283 run_test 270e "DoM: lfs find with DoM files test"
22284
22285 test_270f() {
22286         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22287                 skip "Need MDS version at least 2.10.55"
22288
22289         local mdtname=${FSNAME}-MDT0000-mdtlov
22290         local dom=$DIR/$tdir/dom_file
22291         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22292                                                 lod.$mdtname.dom_stripesize)
22293         local dom_limit=131072
22294
22295         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22296         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22297                                                 lod.$mdtname.dom_stripesize)
22298         [ ${dom_limit} -eq ${dom_current} ] ||
22299                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22300
22301         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22302         $LFS setstripe -d $DIR/$tdir
22303         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22304                 error "Can't set directory default striping"
22305
22306         # exceed maximum stripe size
22307         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22308                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22309         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22310                 error "Able to create DoM component size more than LOD limit"
22311
22312         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22313         dom_current=$(do_facet mds1 $LCTL get_param -n \
22314                                                 lod.$mdtname.dom_stripesize)
22315         [ 0 -eq ${dom_current} ] ||
22316                 error "Can't set zero DoM stripe limit"
22317         rm $dom
22318
22319         # attempt to create DoM file on server with disabled DoM should
22320         # remove DoM entry from layout and be succeed
22321         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22322                 error "Can't create DoM file (DoM is disabled)"
22323         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22324                 error "File has DoM component while DoM is disabled"
22325         rm $dom
22326
22327         # attempt to create DoM file with only DoM stripe should return error
22328         $LFS setstripe -E $dom_limit -L mdt $dom &&
22329                 error "Able to create DoM-only file while DoM is disabled"
22330
22331         # too low values to be aligned with smallest stripe size 64K
22332         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22333         dom_current=$(do_facet mds1 $LCTL get_param -n \
22334                                                 lod.$mdtname.dom_stripesize)
22335         [ 30000 -eq ${dom_current} ] &&
22336                 error "Can set too small DoM stripe limit"
22337
22338         # 64K is a minimal stripe size in Lustre, expect limit of that size
22339         [ 65536 -eq ${dom_current} ] ||
22340                 error "Limit is not set to 64K but ${dom_current}"
22341
22342         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22343         dom_current=$(do_facet mds1 $LCTL get_param -n \
22344                                                 lod.$mdtname.dom_stripesize)
22345         echo $dom_current
22346         [ 2147483648 -eq ${dom_current} ] &&
22347                 error "Can set too large DoM stripe limit"
22348
22349         do_facet mds1 $LCTL set_param -n \
22350                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22351         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22352                 error "Can't create DoM component size after limit change"
22353         do_facet mds1 $LCTL set_param -n \
22354                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22355         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22356                 error "Can't create DoM file after limit decrease"
22357         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22358                 error "Can create big DoM component after limit decrease"
22359         touch ${dom}_def ||
22360                 error "Can't create file with old default layout"
22361
22362         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22363         return 0
22364 }
22365 run_test 270f "DoM: maximum DoM stripe size checks"
22366
22367 test_270g() {
22368         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22369                 skip "Need MDS version at least 2.13.52"
22370         local dom=$DIR/$tdir/$tfile
22371
22372         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22373         local lodname=${FSNAME}-MDT0000-mdtlov
22374
22375         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22376         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22377         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22378         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22379
22380         local dom_limit=1024
22381         local dom_threshold="50%"
22382
22383         $LFS setstripe -d $DIR/$tdir
22384         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22385                 error "Can't set directory default striping"
22386
22387         do_facet mds1 $LCTL set_param -n \
22388                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22389         # set 0 threshold and create DOM file to change tunable stripesize
22390         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22391         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22392                 error "Failed to create $dom file"
22393         # now tunable dom_cur_stripesize should reach maximum
22394         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22395                                         lod.${lodname}.dom_stripesize_cur_kb)
22396         [[ $dom_current == $dom_limit ]] ||
22397                 error "Current DOM stripesize is not maximum"
22398         rm $dom
22399
22400         # set threshold for further tests
22401         do_facet mds1 $LCTL set_param -n \
22402                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22403         echo "DOM threshold is $dom_threshold free space"
22404         local dom_def
22405         local dom_set
22406         # Spoof bfree to exceed threshold
22407         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22408         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22409         for spfree in 40 20 0 15 30 55; do
22410                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22411                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22412                         error "Failed to create $dom file"
22413                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22414                                         lod.${lodname}.dom_stripesize_cur_kb)
22415                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22416                 [[ $dom_def != $dom_current ]] ||
22417                         error "Default stripe size was not changed"
22418                 if (( spfree > 0 )) ; then
22419                         dom_set=$($LFS getstripe -S $dom)
22420                         (( dom_set == dom_def * 1024 )) ||
22421                                 error "DOM component size is still old"
22422                 else
22423                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22424                                 error "DoM component is set with no free space"
22425                 fi
22426                 rm $dom
22427                 dom_current=$dom_def
22428         done
22429 }
22430 run_test 270g "DoM: default DoM stripe size depends on free space"
22431
22432 test_270h() {
22433         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22434                 skip "Need MDS version at least 2.13.53"
22435
22436         local mdtname=${FSNAME}-MDT0000-mdtlov
22437         local dom=$DIR/$tdir/$tfile
22438         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22439
22440         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22441         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22442
22443         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22444         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22445                 error "can't create OST file"
22446         # mirrored file with DOM entry in the second mirror
22447         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22448                 error "can't create mirror with DoM component"
22449
22450         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22451
22452         # DOM component in the middle and has other enries in the same mirror,
22453         # should succeed but lost DoM component
22454         $LFS setstripe --copy=${dom}_1 $dom ||
22455                 error "Can't create file from OST|DOM mirror layout"
22456         # check new file has no DoM layout after all
22457         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22458                 error "File has DoM component while DoM is disabled"
22459 }
22460 run_test 270h "DoM: DoM stripe removal when disabled on server"
22461
22462 test_270i() {
22463         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22464                 skip "Need MDS version at least 2.14.54"
22465
22466         mkdir $DIR/$tdir
22467         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22468                 error "setstripe should fail" || true
22469 }
22470 run_test 270i "DoM: setting invalid DoM striping should fail"
22471
22472 test_271a() {
22473         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22474                 skip "Need MDS version at least 2.10.55"
22475
22476         local dom=$DIR/$tdir/dom
22477
22478         mkdir -p $DIR/$tdir
22479
22480         $LFS setstripe -E 1024K -L mdt $dom
22481
22482         lctl set_param -n mdc.*.stats=clear
22483         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22484         cat $dom > /dev/null
22485         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22486         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22487         ls $dom
22488         rm -f $dom
22489 }
22490 run_test 271a "DoM: data is cached for read after write"
22491
22492 test_271b() {
22493         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22494                 skip "Need MDS version at least 2.10.55"
22495
22496         local dom=$DIR/$tdir/dom
22497
22498         mkdir -p $DIR/$tdir
22499
22500         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22501
22502         lctl set_param -n mdc.*.stats=clear
22503         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22504         cancel_lru_locks mdc
22505         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22506         # second stat to check size is cached on client
22507         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22508         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22509         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22510         rm -f $dom
22511 }
22512 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22513
22514 test_271ba() {
22515         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22516                 skip "Need MDS version at least 2.10.55"
22517
22518         local dom=$DIR/$tdir/dom
22519
22520         mkdir -p $DIR/$tdir
22521
22522         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22523
22524         lctl set_param -n mdc.*.stats=clear
22525         lctl set_param -n osc.*.stats=clear
22526         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22527         cancel_lru_locks mdc
22528         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22529         # second stat to check size is cached on client
22530         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22531         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22532         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22533         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22534         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22535         rm -f $dom
22536 }
22537 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22538
22539
22540 get_mdc_stats() {
22541         local mdtidx=$1
22542         local param=$2
22543         local mdt=MDT$(printf %04x $mdtidx)
22544
22545         if [ -z $param ]; then
22546                 lctl get_param -n mdc.*$mdt*.stats
22547         else
22548                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22549         fi
22550 }
22551
22552 test_271c() {
22553         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22554                 skip "Need MDS version at least 2.10.55"
22555
22556         local dom=$DIR/$tdir/dom
22557
22558         mkdir -p $DIR/$tdir
22559
22560         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22561
22562         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22563         local facet=mds$((mdtidx + 1))
22564
22565         cancel_lru_locks mdc
22566         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22567         createmany -o $dom 1000
22568         lctl set_param -n mdc.*.stats=clear
22569         smalliomany -w $dom 1000 200
22570         get_mdc_stats $mdtidx
22571         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22572         # Each file has 1 open, 1 IO enqueues, total 2000
22573         # but now we have also +1 getxattr for security.capability, total 3000
22574         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22575         unlinkmany $dom 1000
22576
22577         cancel_lru_locks mdc
22578         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22579         createmany -o $dom 1000
22580         lctl set_param -n mdc.*.stats=clear
22581         smalliomany -w $dom 1000 200
22582         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22583         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22584         # for OPEN and IO lock.
22585         [ $((enq - enq_2)) -ge 1000 ] ||
22586                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22587         unlinkmany $dom 1000
22588         return 0
22589 }
22590 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22591
22592 cleanup_271def_tests() {
22593         trap 0
22594         rm -f $1
22595 }
22596
22597 test_271d() {
22598         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22599                 skip "Need MDS version at least 2.10.57"
22600
22601         local dom=$DIR/$tdir/dom
22602         local tmp=$TMP/$tfile
22603         trap "cleanup_271def_tests $tmp" EXIT
22604
22605         mkdir -p $DIR/$tdir
22606
22607         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22608
22609         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22610
22611         cancel_lru_locks mdc
22612         dd if=/dev/urandom of=$tmp bs=1000 count=1
22613         dd if=$tmp of=$dom bs=1000 count=1
22614         cancel_lru_locks mdc
22615
22616         cat /etc/hosts >> $tmp
22617         lctl set_param -n mdc.*.stats=clear
22618
22619         # append data to the same file it should update local page
22620         echo "Append to the same page"
22621         cat /etc/hosts >> $dom
22622         local num=$(get_mdc_stats $mdtidx ost_read)
22623         local ra=$(get_mdc_stats $mdtidx req_active)
22624         local rw=$(get_mdc_stats $mdtidx req_waittime)
22625
22626         [ -z $num ] || error "$num READ RPC occured"
22627         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22628         echo "... DONE"
22629
22630         # compare content
22631         cmp $tmp $dom || error "file miscompare"
22632
22633         cancel_lru_locks mdc
22634         lctl set_param -n mdc.*.stats=clear
22635
22636         echo "Open and read file"
22637         cat $dom > /dev/null
22638         local num=$(get_mdc_stats $mdtidx ost_read)
22639         local ra=$(get_mdc_stats $mdtidx req_active)
22640         local rw=$(get_mdc_stats $mdtidx req_waittime)
22641
22642         [ -z $num ] || error "$num READ RPC occured"
22643         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22644         echo "... DONE"
22645
22646         # compare content
22647         cmp $tmp $dom || error "file miscompare"
22648
22649         return 0
22650 }
22651 run_test 271d "DoM: read on open (1K file in reply buffer)"
22652
22653 test_271f() {
22654         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22655                 skip "Need MDS version at least 2.10.57"
22656
22657         local dom=$DIR/$tdir/dom
22658         local tmp=$TMP/$tfile
22659         trap "cleanup_271def_tests $tmp" EXIT
22660
22661         mkdir -p $DIR/$tdir
22662
22663         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22664
22665         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22666
22667         cancel_lru_locks mdc
22668         dd if=/dev/urandom of=$tmp bs=265000 count=1
22669         dd if=$tmp of=$dom bs=265000 count=1
22670         cancel_lru_locks mdc
22671         cat /etc/hosts >> $tmp
22672         lctl set_param -n mdc.*.stats=clear
22673
22674         echo "Append to the same page"
22675         cat /etc/hosts >> $dom
22676         local num=$(get_mdc_stats $mdtidx ost_read)
22677         local ra=$(get_mdc_stats $mdtidx req_active)
22678         local rw=$(get_mdc_stats $mdtidx req_waittime)
22679
22680         [ -z $num ] || error "$num READ RPC occured"
22681         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22682         echo "... DONE"
22683
22684         # compare content
22685         cmp $tmp $dom || error "file miscompare"
22686
22687         cancel_lru_locks mdc
22688         lctl set_param -n mdc.*.stats=clear
22689
22690         echo "Open and read file"
22691         cat $dom > /dev/null
22692         local num=$(get_mdc_stats $mdtidx ost_read)
22693         local ra=$(get_mdc_stats $mdtidx req_active)
22694         local rw=$(get_mdc_stats $mdtidx req_waittime)
22695
22696         [ -z $num ] && num=0
22697         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22698         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22699         echo "... DONE"
22700
22701         # compare content
22702         cmp $tmp $dom || error "file miscompare"
22703
22704         return 0
22705 }
22706 run_test 271f "DoM: read on open (200K file and read tail)"
22707
22708 test_271g() {
22709         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22710                 skip "Skipping due to old client or server version"
22711
22712         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22713         # to get layout
22714         $CHECKSTAT -t file $DIR1/$tfile
22715
22716         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22717         MULTIOP_PID=$!
22718         sleep 1
22719         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22720         $LCTL set_param fail_loc=0x80000314
22721         rm $DIR1/$tfile || error "Unlink fails"
22722         RC=$?
22723         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22724         [ $RC -eq 0 ] || error "Failed write to stale object"
22725 }
22726 run_test 271g "Discard DoM data vs client flush race"
22727
22728 test_272a() {
22729         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22730                 skip "Need MDS version at least 2.11.50"
22731
22732         local dom=$DIR/$tdir/dom
22733         mkdir -p $DIR/$tdir
22734
22735         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22736         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22737                 error "failed to write data into $dom"
22738         local old_md5=$(md5sum $dom)
22739
22740         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22741                 error "failed to migrate to the same DoM component"
22742
22743         local new_md5=$(md5sum $dom)
22744
22745         [ "$old_md5" == "$new_md5" ] ||
22746                 error "md5sum differ: $old_md5, $new_md5"
22747
22748         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22749                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22750 }
22751 run_test 272a "DoM migration: new layout with the same DOM component"
22752
22753 test_272b() {
22754         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22755                 skip "Need MDS version at least 2.11.50"
22756
22757         local dom=$DIR/$tdir/dom
22758         mkdir -p $DIR/$tdir
22759         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22760
22761         local mdtidx=$($LFS getstripe -m $dom)
22762         local mdtname=MDT$(printf %04x $mdtidx)
22763         local facet=mds$((mdtidx + 1))
22764
22765         local mdtfree1=$(do_facet $facet \
22766                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22767         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22768                 error "failed to write data into $dom"
22769         local old_md5=$(md5sum $dom)
22770         cancel_lru_locks mdc
22771         local mdtfree1=$(do_facet $facet \
22772                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22773
22774         $LFS migrate -c2 $dom ||
22775                 error "failed to migrate to the new composite layout"
22776         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22777                 error "MDT stripe was not removed"
22778
22779         cancel_lru_locks mdc
22780         local new_md5=$(md5sum $dom)
22781         [ "$old_md5" == "$new_md5" ] ||
22782                 error "$old_md5 != $new_md5"
22783
22784         # Skip free space checks with ZFS
22785         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22786                 local mdtfree2=$(do_facet $facet \
22787                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22788                 [ $mdtfree2 -gt $mdtfree1 ] ||
22789                         error "MDT space is not freed after migration"
22790         fi
22791         return 0
22792 }
22793 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22794
22795 test_272c() {
22796         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22797                 skip "Need MDS version at least 2.11.50"
22798
22799         local dom=$DIR/$tdir/$tfile
22800         mkdir -p $DIR/$tdir
22801         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22802
22803         local mdtidx=$($LFS getstripe -m $dom)
22804         local mdtname=MDT$(printf %04x $mdtidx)
22805         local facet=mds$((mdtidx + 1))
22806
22807         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22808                 error "failed to write data into $dom"
22809         local old_md5=$(md5sum $dom)
22810         cancel_lru_locks mdc
22811         local mdtfree1=$(do_facet $facet \
22812                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22813
22814         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22815                 error "failed to migrate to the new composite layout"
22816         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22817                 error "MDT stripe was not removed"
22818
22819         cancel_lru_locks mdc
22820         local new_md5=$(md5sum $dom)
22821         [ "$old_md5" == "$new_md5" ] ||
22822                 error "$old_md5 != $new_md5"
22823
22824         # Skip free space checks with ZFS
22825         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22826                 local mdtfree2=$(do_facet $facet \
22827                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22828                 [ $mdtfree2 -gt $mdtfree1 ] ||
22829                         error "MDS space is not freed after migration"
22830         fi
22831         return 0
22832 }
22833 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22834
22835 test_272d() {
22836         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22837                 skip "Need MDS version at least 2.12.55"
22838
22839         local dom=$DIR/$tdir/$tfile
22840         mkdir -p $DIR/$tdir
22841         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22842
22843         local mdtidx=$($LFS getstripe -m $dom)
22844         local mdtname=MDT$(printf %04x $mdtidx)
22845         local facet=mds$((mdtidx + 1))
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 mdc
22851         local mdtfree1=$(do_facet $facet \
22852                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22853
22854         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22855                 error "failed mirroring to the new composite layout"
22856         $LFS mirror resync $dom ||
22857                 error "failed mirror resync"
22858         $LFS mirror split --mirror-id 1 -d $dom ||
22859                 error "failed mirror split"
22860
22861         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22862                 error "MDT stripe was not removed"
22863
22864         cancel_lru_locks mdc
22865         local new_md5=$(md5sum $dom)
22866         [ "$old_md5" == "$new_md5" ] ||
22867                 error "$old_md5 != $new_md5"
22868
22869         # Skip free space checks with ZFS
22870         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22871                 local mdtfree2=$(do_facet $facet \
22872                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22873                 [ $mdtfree2 -gt $mdtfree1 ] ||
22874                         error "MDS space is not freed after DOM mirror deletion"
22875         fi
22876         return 0
22877 }
22878 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22879
22880 test_272e() {
22881         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22882                 skip "Need MDS version at least 2.12.55"
22883
22884         local dom=$DIR/$tdir/$tfile
22885         mkdir -p $DIR/$tdir
22886         $LFS setstripe -c 2 $dom
22887
22888         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22889                 error "failed to write data into $dom"
22890         local old_md5=$(md5sum $dom)
22891         cancel_lru_locks
22892
22893         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22894                 error "failed mirroring to the DOM layout"
22895         $LFS mirror resync $dom ||
22896                 error "failed mirror resync"
22897         $LFS mirror split --mirror-id 1 -d $dom ||
22898                 error "failed mirror split"
22899
22900         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22901                 error "MDT stripe wasn't set"
22902
22903         cancel_lru_locks
22904         local new_md5=$(md5sum $dom)
22905         [ "$old_md5" == "$new_md5" ] ||
22906                 error "$old_md5 != $new_md5"
22907
22908         return 0
22909 }
22910 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22911
22912 test_272f() {
22913         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22914                 skip "Need MDS version at least 2.12.55"
22915
22916         local dom=$DIR/$tdir/$tfile
22917         mkdir -p $DIR/$tdir
22918         $LFS setstripe -c 2 $dom
22919
22920         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22921                 error "failed to write data into $dom"
22922         local old_md5=$(md5sum $dom)
22923         cancel_lru_locks
22924
22925         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22926                 error "failed migrating to the DOM file"
22927
22928         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22929                 error "MDT stripe wasn't set"
22930
22931         cancel_lru_locks
22932         local new_md5=$(md5sum $dom)
22933         [ "$old_md5" != "$new_md5" ] &&
22934                 error "$old_md5 != $new_md5"
22935
22936         return 0
22937 }
22938 run_test 272f "DoM migration: OST-striped file to DOM file"
22939
22940 test_273a() {
22941         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22942                 skip "Need MDS version at least 2.11.50"
22943
22944         # Layout swap cannot be done if either file has DOM component,
22945         # this will never be supported, migration should be used instead
22946
22947         local dom=$DIR/$tdir/$tfile
22948         mkdir -p $DIR/$tdir
22949
22950         $LFS setstripe -c2 ${dom}_plain
22951         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22952         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22953                 error "can swap layout with DoM component"
22954         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22955                 error "can swap layout with DoM component"
22956
22957         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22958         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22959                 error "can swap layout with DoM component"
22960         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22961                 error "can swap layout with DoM component"
22962         return 0
22963 }
22964 run_test 273a "DoM: layout swapping should fail with DOM"
22965
22966 test_273b() {
22967         mkdir -p $DIR/$tdir
22968         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22969
22970 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22971         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22972
22973         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22974 }
22975 run_test 273b "DoM: race writeback and object destroy"
22976
22977 test_275() {
22978         remote_ost_nodsh && skip "remote OST with nodsh"
22979         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22980                 skip "Need OST version >= 2.10.57"
22981
22982         local file=$DIR/$tfile
22983         local oss
22984
22985         oss=$(comma_list $(osts_nodes))
22986
22987         dd if=/dev/urandom of=$file bs=1M count=2 ||
22988                 error "failed to create a file"
22989         cancel_lru_locks osc
22990
22991         #lock 1
22992         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22993                 error "failed to read a file"
22994
22995 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22996         $LCTL set_param fail_loc=0x8000031f
22997
22998         cancel_lru_locks osc &
22999         sleep 1
23000
23001 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23002         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23003         #IO takes another lock, but matches the PENDING one
23004         #and places it to the IO RPC
23005         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23006                 error "failed to read a file with PENDING lock"
23007 }
23008 run_test 275 "Read on a canceled duplicate lock"
23009
23010 test_276() {
23011         remote_ost_nodsh && skip "remote OST with nodsh"
23012         local pid
23013
23014         do_facet ost1 "(while true; do \
23015                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23016                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23017         pid=$!
23018
23019         for LOOP in $(seq 20); do
23020                 stop ost1
23021                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23022         done
23023         kill -9 $pid
23024         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23025                 rm $TMP/sanity_276_pid"
23026 }
23027 run_test 276 "Race between mount and obd_statfs"
23028
23029 test_277() {
23030         $LCTL set_param ldlm.namespaces.*.lru_size=0
23031         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23032         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23033                         grep ^used_mb | awk '{print $2}')
23034         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23035         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23036                 oflag=direct conv=notrunc
23037         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23038                         grep ^used_mb | awk '{print $2}')
23039         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23040 }
23041 run_test 277 "Direct IO shall drop page cache"
23042
23043 test_278() {
23044         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23045         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23046         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23047                 skip "needs the same host for mdt1 mdt2" && return
23048
23049         local pid1
23050         local pid2
23051
23052 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23053         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23054         stop mds2 &
23055         pid2=$!
23056
23057         stop mds1
23058
23059         echo "Starting MDTs"
23060         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23061         wait $pid2
23062 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23063 #will return NULL
23064         do_facet mds2 $LCTL set_param fail_loc=0
23065
23066         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23067         wait_recovery_complete mds2
23068 }
23069 run_test 278 "Race starting MDS between MDTs stop/start"
23070
23071 test_280() {
23072         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23073                 skip "Need MGS version at least 2.13.52"
23074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23075         combined_mgs_mds || skip "needs combined MGS/MDT"
23076
23077         umount_client $MOUNT
23078 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23079         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23080
23081         mount_client $MOUNT &
23082         sleep 1
23083         stop mgs || error "stop mgs failed"
23084         #for a race mgs would crash
23085         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23086         # make sure we unmount client before remounting
23087         wait
23088         umount_client $MOUNT
23089         mount_client $MOUNT || error "mount client failed"
23090 }
23091 run_test 280 "Race between MGS umount and client llog processing"
23092
23093 cleanup_test_300() {
23094         trap 0
23095         umask $SAVE_UMASK
23096 }
23097 test_striped_dir() {
23098         local mdt_index=$1
23099         local stripe_count
23100         local stripe_index
23101
23102         mkdir -p $DIR/$tdir
23103
23104         SAVE_UMASK=$(umask)
23105         trap cleanup_test_300 RETURN EXIT
23106
23107         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23108                                                 $DIR/$tdir/striped_dir ||
23109                 error "set striped dir error"
23110
23111         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23112         [ "$mode" = "755" ] || error "expect 755 got $mode"
23113
23114         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23115                 error "getdirstripe failed"
23116         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23117         if [ "$stripe_count" != "2" ]; then
23118                 error "1:stripe_count is $stripe_count, expect 2"
23119         fi
23120         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23121         if [ "$stripe_count" != "2" ]; then
23122                 error "2:stripe_count is $stripe_count, expect 2"
23123         fi
23124
23125         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23126         if [ "$stripe_index" != "$mdt_index" ]; then
23127                 error "stripe_index is $stripe_index, expect $mdt_index"
23128         fi
23129
23130         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23131                 error "nlink error after create striped dir"
23132
23133         mkdir $DIR/$tdir/striped_dir/a
23134         mkdir $DIR/$tdir/striped_dir/b
23135
23136         stat $DIR/$tdir/striped_dir/a ||
23137                 error "create dir under striped dir failed"
23138         stat $DIR/$tdir/striped_dir/b ||
23139                 error "create dir under striped dir failed"
23140
23141         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23142                 error "nlink error after mkdir"
23143
23144         rmdir $DIR/$tdir/striped_dir/a
23145         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23146                 error "nlink error after rmdir"
23147
23148         rmdir $DIR/$tdir/striped_dir/b
23149         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23150                 error "nlink error after rmdir"
23151
23152         chattr +i $DIR/$tdir/striped_dir
23153         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23154                 error "immutable flags not working under striped dir!"
23155         chattr -i $DIR/$tdir/striped_dir
23156
23157         rmdir $DIR/$tdir/striped_dir ||
23158                 error "rmdir striped dir error"
23159
23160         cleanup_test_300
23161
23162         true
23163 }
23164
23165 test_300a() {
23166         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23167                 skip "skipped for lustre < 2.7.0"
23168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23169         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23170
23171         test_striped_dir 0 || error "failed on striped dir on MDT0"
23172         test_striped_dir 1 || error "failed on striped dir on MDT0"
23173 }
23174 run_test 300a "basic striped dir sanity test"
23175
23176 test_300b() {
23177         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23178                 skip "skipped for lustre < 2.7.0"
23179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23180         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23181
23182         local i
23183         local mtime1
23184         local mtime2
23185         local mtime3
23186
23187         test_mkdir $DIR/$tdir || error "mkdir fail"
23188         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23189                 error "set striped dir error"
23190         for i in {0..9}; do
23191                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23192                 sleep 1
23193                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23194                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23195                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23196                 sleep 1
23197                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23198                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23199                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23200         done
23201         true
23202 }
23203 run_test 300b "check ctime/mtime for striped dir"
23204
23205 test_300c() {
23206         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23207                 skip "skipped for lustre < 2.7.0"
23208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23209         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23210
23211         local file_count
23212
23213         mkdir_on_mdt0 $DIR/$tdir
23214         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23215                 error "set striped dir error"
23216
23217         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23218                 error "chown striped dir failed"
23219
23220         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23221                 error "create 5k files failed"
23222
23223         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23224
23225         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23226
23227         rm -rf $DIR/$tdir
23228 }
23229 run_test 300c "chown && check ls under striped directory"
23230
23231 test_300d() {
23232         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23233                 skip "skipped for lustre < 2.7.0"
23234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23236
23237         local stripe_count
23238         local file
23239
23240         mkdir -p $DIR/$tdir
23241         $LFS setstripe -c 2 $DIR/$tdir
23242
23243         #local striped directory
23244         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23245                 error "set striped dir error"
23246         #look at the directories for debug purposes
23247         ls -l $DIR/$tdir
23248         $LFS getdirstripe $DIR/$tdir
23249         ls -l $DIR/$tdir/striped_dir
23250         $LFS getdirstripe $DIR/$tdir/striped_dir
23251         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23252                 error "create 10 files failed"
23253
23254         #remote striped directory
23255         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23256                 error "set striped dir error"
23257         #look at the directories for debug purposes
23258         ls -l $DIR/$tdir
23259         $LFS getdirstripe $DIR/$tdir
23260         ls -l $DIR/$tdir/remote_striped_dir
23261         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23262         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23263                 error "create 10 files failed"
23264
23265         for file in $(find $DIR/$tdir); do
23266                 stripe_count=$($LFS getstripe -c $file)
23267                 [ $stripe_count -eq 2 ] ||
23268                         error "wrong stripe $stripe_count for $file"
23269         done
23270
23271         rm -rf $DIR/$tdir
23272 }
23273 run_test 300d "check default stripe under striped directory"
23274
23275 test_300e() {
23276         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23277                 skip "Need MDS version at least 2.7.55"
23278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23279         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23280
23281         local stripe_count
23282         local file
23283
23284         mkdir -p $DIR/$tdir
23285
23286         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23287                 error "set striped dir error"
23288
23289         touch $DIR/$tdir/striped_dir/a
23290         touch $DIR/$tdir/striped_dir/b
23291         touch $DIR/$tdir/striped_dir/c
23292
23293         mkdir $DIR/$tdir/striped_dir/dir_a
23294         mkdir $DIR/$tdir/striped_dir/dir_b
23295         mkdir $DIR/$tdir/striped_dir/dir_c
23296
23297         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23298                 error "set striped adir under striped dir error"
23299
23300         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23301                 error "set striped bdir under striped dir error"
23302
23303         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23304                 error "set striped cdir under striped dir error"
23305
23306         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23307                 error "rename dir under striped dir fails"
23308
23309         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23310                 error "rename dir under different stripes fails"
23311
23312         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23313                 error "rename file under striped dir should succeed"
23314
23315         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23316                 error "rename dir under striped dir should succeed"
23317
23318         rm -rf $DIR/$tdir
23319 }
23320 run_test 300e "check rename under striped directory"
23321
23322 test_300f() {
23323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23324         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23325         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23326                 skip "Need MDS version at least 2.7.55"
23327
23328         local stripe_count
23329         local file
23330
23331         rm -rf $DIR/$tdir
23332         mkdir -p $DIR/$tdir
23333
23334         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23335                 error "set striped dir error"
23336
23337         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23338                 error "set striped dir error"
23339
23340         touch $DIR/$tdir/striped_dir/a
23341         mkdir $DIR/$tdir/striped_dir/dir_a
23342         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23343                 error "create striped dir under striped dir fails"
23344
23345         touch $DIR/$tdir/striped_dir1/b
23346         mkdir $DIR/$tdir/striped_dir1/dir_b
23347         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23348                 error "create striped dir under striped dir fails"
23349
23350         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23351                 error "rename dir under different striped dir should fail"
23352
23353         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23354                 error "rename striped dir under diff striped dir should fail"
23355
23356         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23357                 error "rename file under diff striped dirs fails"
23358
23359         rm -rf $DIR/$tdir
23360 }
23361 run_test 300f "check rename cross striped directory"
23362
23363 test_300_check_default_striped_dir()
23364 {
23365         local dirname=$1
23366         local default_count=$2
23367         local default_index=$3
23368         local stripe_count
23369         local stripe_index
23370         local dir_stripe_index
23371         local dir
23372
23373         echo "checking $dirname $default_count $default_index"
23374         $LFS setdirstripe -D -c $default_count -i $default_index \
23375                                 -H all_char $DIR/$tdir/$dirname ||
23376                 error "set default stripe on striped dir error"
23377         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23378         [ $stripe_count -eq $default_count ] ||
23379                 error "expect $default_count get $stripe_count for $dirname"
23380
23381         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23382         [ $stripe_index -eq $default_index ] ||
23383                 error "expect $default_index get $stripe_index for $dirname"
23384
23385         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23386                                                 error "create dirs failed"
23387
23388         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23389         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23390         for dir in $(find $DIR/$tdir/$dirname/*); do
23391                 stripe_count=$($LFS getdirstripe -c $dir)
23392                 (( $stripe_count == $default_count )) ||
23393                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23394                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23395                 error "stripe count $default_count != $stripe_count for $dir"
23396
23397                 stripe_index=$($LFS getdirstripe -i $dir)
23398                 [ $default_index -eq -1 ] ||
23399                         [ $stripe_index -eq $default_index ] ||
23400                         error "$stripe_index != $default_index for $dir"
23401
23402                 #check default stripe
23403                 stripe_count=$($LFS getdirstripe -D -c $dir)
23404                 [ $stripe_count -eq $default_count ] ||
23405                 error "default count $default_count != $stripe_count for $dir"
23406
23407                 stripe_index=$($LFS getdirstripe -D -i $dir)
23408                 [ $stripe_index -eq $default_index ] ||
23409                 error "default index $default_index != $stripe_index for $dir"
23410         done
23411         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23412 }
23413
23414 test_300g() {
23415         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23416         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23417                 skip "Need MDS version at least 2.7.55"
23418
23419         local dir
23420         local stripe_count
23421         local stripe_index
23422
23423         mkdir_on_mdt0 $DIR/$tdir
23424         mkdir $DIR/$tdir/normal_dir
23425
23426         #Checking when client cache stripe index
23427         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23428         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23429                 error "create striped_dir failed"
23430
23431         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23432                 error "create dir0 fails"
23433         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23434         [ $stripe_index -eq 0 ] ||
23435                 error "dir0 expect index 0 got $stripe_index"
23436
23437         mkdir $DIR/$tdir/striped_dir/dir1 ||
23438                 error "create dir1 fails"
23439         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23440         [ $stripe_index -eq 1 ] ||
23441                 error "dir1 expect index 1 got $stripe_index"
23442
23443         #check default stripe count/stripe index
23444         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23445         test_300_check_default_striped_dir normal_dir 1 0
23446         test_300_check_default_striped_dir normal_dir -1 1
23447         test_300_check_default_striped_dir normal_dir 2 -1
23448
23449         #delete default stripe information
23450         echo "delete default stripeEA"
23451         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23452                 error "set default stripe on striped dir error"
23453
23454         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23455         for dir in $(find $DIR/$tdir/normal_dir/*); do
23456                 stripe_count=$($LFS getdirstripe -c $dir)
23457                 [ $stripe_count -eq 0 ] ||
23458                         error "expect 1 get $stripe_count for $dir"
23459         done
23460 }
23461 run_test 300g "check default striped directory for normal directory"
23462
23463 test_300h() {
23464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23465         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23466                 skip "Need MDS version at least 2.7.55"
23467
23468         local dir
23469         local stripe_count
23470
23471         mkdir $DIR/$tdir
23472         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23473                 error "set striped dir error"
23474
23475         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23476         test_300_check_default_striped_dir striped_dir 1 0
23477         test_300_check_default_striped_dir striped_dir -1 1
23478         test_300_check_default_striped_dir striped_dir 2 -1
23479
23480         #delete default stripe information
23481         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23482                 error "set default stripe on striped dir error"
23483
23484         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23485         for dir in $(find $DIR/$tdir/striped_dir/*); do
23486                 stripe_count=$($LFS getdirstripe -c $dir)
23487                 [ $stripe_count -eq 0 ] ||
23488                         error "expect 1 get $stripe_count for $dir"
23489         done
23490 }
23491 run_test 300h "check default striped directory for striped directory"
23492
23493 test_300i() {
23494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23495         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23496         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23497                 skip "Need MDS version at least 2.7.55"
23498
23499         local stripe_count
23500         local file
23501
23502         mkdir $DIR/$tdir
23503
23504         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23505                 error "set striped dir error"
23506
23507         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23508                 error "create files under striped dir failed"
23509
23510         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23511                 error "set striped hashdir error"
23512
23513         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23514                 error "create dir0 under hash dir failed"
23515         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23516                 error "create dir1 under hash dir failed"
23517         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23518                 error "create dir2 under hash dir failed"
23519
23520         # unfortunately, we need to umount to clear dir layout cache for now
23521         # once we fully implement dir layout, we can drop this
23522         umount_client $MOUNT || error "umount failed"
23523         mount_client $MOUNT || error "mount failed"
23524
23525         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23526         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23527         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23528
23529         #set the stripe to be unknown hash type
23530         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23531         $LCTL set_param fail_loc=0x1901
23532         for ((i = 0; i < 10; i++)); do
23533                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23534                         error "stat f-$i failed"
23535                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23536         done
23537
23538         touch $DIR/$tdir/striped_dir/f0 &&
23539                 error "create under striped dir with unknown hash should fail"
23540
23541         $LCTL set_param fail_loc=0
23542
23543         umount_client $MOUNT || error "umount failed"
23544         mount_client $MOUNT || error "mount failed"
23545
23546         return 0
23547 }
23548 run_test 300i "client handle unknown hash type striped directory"
23549
23550 test_300j() {
23551         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23553         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23554                 skip "Need MDS version at least 2.7.55"
23555
23556         local stripe_count
23557         local file
23558
23559         mkdir $DIR/$tdir
23560
23561         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23562         $LCTL set_param fail_loc=0x1702
23563         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23564                 error "set striped dir error"
23565
23566         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23567                 error "create files under striped dir failed"
23568
23569         $LCTL set_param fail_loc=0
23570
23571         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23572
23573         return 0
23574 }
23575 run_test 300j "test large update record"
23576
23577 test_300k() {
23578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23579         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23580         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23581                 skip "Need MDS version at least 2.7.55"
23582
23583         # this test needs a huge transaction
23584         local kb
23585         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23586              osd*.$FSNAME-MDT0000.kbytestotal")
23587         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23588
23589         local stripe_count
23590         local file
23591
23592         mkdir $DIR/$tdir
23593
23594         #define OBD_FAIL_LARGE_STRIPE   0x1703
23595         $LCTL set_param fail_loc=0x1703
23596         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23597                 error "set striped dir error"
23598         $LCTL set_param fail_loc=0
23599
23600         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23601                 error "getstripeddir fails"
23602         rm -rf $DIR/$tdir/striped_dir ||
23603                 error "unlink striped dir fails"
23604
23605         return 0
23606 }
23607 run_test 300k "test large striped directory"
23608
23609 test_300l() {
23610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23611         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23612         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23613                 skip "Need MDS version at least 2.7.55"
23614
23615         local stripe_index
23616
23617         test_mkdir -p $DIR/$tdir/striped_dir
23618         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23619                         error "chown $RUNAS_ID failed"
23620         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23621                 error "set default striped dir failed"
23622
23623         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23624         $LCTL set_param fail_loc=0x80000158
23625         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23626
23627         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23628         [ $stripe_index -eq 1 ] ||
23629                 error "expect 1 get $stripe_index for $dir"
23630 }
23631 run_test 300l "non-root user to create dir under striped dir with stale layout"
23632
23633 test_300m() {
23634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23635         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23636         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23637                 skip "Need MDS version at least 2.7.55"
23638
23639         mkdir -p $DIR/$tdir/striped_dir
23640         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23641                 error "set default stripes dir error"
23642
23643         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23644
23645         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23646         [ $stripe_count -eq 0 ] ||
23647                         error "expect 0 get $stripe_count for a"
23648
23649         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23650                 error "set default stripes dir error"
23651
23652         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23653
23654         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23655         [ $stripe_count -eq 0 ] ||
23656                         error "expect 0 get $stripe_count for b"
23657
23658         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23659                 error "set default stripes dir error"
23660
23661         mkdir $DIR/$tdir/striped_dir/c &&
23662                 error "default stripe_index is invalid, mkdir c should fails"
23663
23664         rm -rf $DIR/$tdir || error "rmdir fails"
23665 }
23666 run_test 300m "setstriped directory on single MDT FS"
23667
23668 cleanup_300n() {
23669         local list=$(comma_list $(mdts_nodes))
23670
23671         trap 0
23672         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23673 }
23674
23675 test_300n() {
23676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23677         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23678         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23679                 skip "Need MDS version at least 2.7.55"
23680         remote_mds_nodsh && skip "remote MDS with nodsh"
23681
23682         local stripe_index
23683         local list=$(comma_list $(mdts_nodes))
23684
23685         trap cleanup_300n RETURN EXIT
23686         mkdir -p $DIR/$tdir
23687         chmod 777 $DIR/$tdir
23688         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23689                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23690                 error "create striped dir succeeds with gid=0"
23691
23692         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23693         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23694                 error "create striped dir fails with gid=-1"
23695
23696         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23697         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23698                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23699                 error "set default striped dir succeeds with gid=0"
23700
23701
23702         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23703         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23704                 error "set default striped dir fails with gid=-1"
23705
23706
23707         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23708         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23709                                         error "create test_dir fails"
23710         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23711                                         error "create test_dir1 fails"
23712         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23713                                         error "create test_dir2 fails"
23714         cleanup_300n
23715 }
23716 run_test 300n "non-root user to create dir under striped dir with default EA"
23717
23718 test_300o() {
23719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23720         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23721         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23722                 skip "Need MDS version at least 2.7.55"
23723
23724         local numfree1
23725         local numfree2
23726
23727         mkdir -p $DIR/$tdir
23728
23729         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23730         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23731         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23732                 skip "not enough free inodes $numfree1 $numfree2"
23733         fi
23734
23735         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23736         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23737         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23738                 skip "not enough free space $numfree1 $numfree2"
23739         fi
23740
23741         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23742                 error "setdirstripe fails"
23743
23744         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23745                 error "create dirs fails"
23746
23747         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23748         ls $DIR/$tdir/striped_dir > /dev/null ||
23749                 error "ls striped dir fails"
23750         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23751                 error "unlink big striped dir fails"
23752 }
23753 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23754
23755 test_300p() {
23756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23757         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23758         remote_mds_nodsh && skip "remote MDS with nodsh"
23759
23760         mkdir_on_mdt0 $DIR/$tdir
23761
23762         #define OBD_FAIL_OUT_ENOSPC     0x1704
23763         do_facet mds2 lctl set_param fail_loc=0x80001704
23764         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23765                  && error "create striped directory should fail"
23766
23767         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23768
23769         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23770         true
23771 }
23772 run_test 300p "create striped directory without space"
23773
23774 test_300q() {
23775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23776         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23777
23778         local fd=$(free_fd)
23779         local cmd="exec $fd<$tdir"
23780         cd $DIR
23781         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23782         eval $cmd
23783         cmd="exec $fd<&-"
23784         trap "eval $cmd" EXIT
23785         cd $tdir || error "cd $tdir fails"
23786         rmdir  ../$tdir || error "rmdir $tdir fails"
23787         mkdir local_dir && error "create dir succeeds"
23788         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23789         eval $cmd
23790         return 0
23791 }
23792 run_test 300q "create remote directory under orphan directory"
23793
23794 test_300r() {
23795         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23796                 skip "Need MDS version at least 2.7.55" && return
23797         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23798
23799         mkdir $DIR/$tdir
23800
23801         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23802                 error "set striped dir error"
23803
23804         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23805                 error "getstripeddir fails"
23806
23807         local stripe_count
23808         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23809                       awk '/lmv_stripe_count:/ { print $2 }')
23810
23811         [ $MDSCOUNT -ne $stripe_count ] &&
23812                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23813
23814         rm -rf $DIR/$tdir/striped_dir ||
23815                 error "unlink striped dir fails"
23816 }
23817 run_test 300r "test -1 striped directory"
23818
23819 test_300s_helper() {
23820         local count=$1
23821
23822         local stripe_dir=$DIR/$tdir/striped_dir.$count
23823
23824         $LFS mkdir -c $count $stripe_dir ||
23825                 error "lfs mkdir -c error"
23826
23827         $LFS getdirstripe $stripe_dir ||
23828                 error "lfs getdirstripe fails"
23829
23830         local stripe_count
23831         stripe_count=$($LFS getdirstripe $stripe_dir |
23832                       awk '/lmv_stripe_count:/ { print $2 }')
23833
23834         [ $count -ne $stripe_count ] &&
23835                 error_noexit "bad stripe count $stripe_count expected $count"
23836
23837         local dupe_stripes
23838         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23839                 awk '/0x/ {count[$1] += 1}; END {
23840                         for (idx in count) {
23841                                 if (count[idx]>1) {
23842                                         print "index " idx " count " count[idx]
23843                                 }
23844                         }
23845                 }')
23846
23847         if [[ -n "$dupe_stripes" ]] ; then
23848                 lfs getdirstripe $stripe_dir
23849                 error_noexit "Dupe MDT above: $dupe_stripes "
23850         fi
23851
23852         rm -rf $stripe_dir ||
23853                 error_noexit "unlink $stripe_dir fails"
23854 }
23855
23856 test_300s() {
23857         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23858                 skip "Need MDS version at least 2.7.55" && return
23859         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23860
23861         mkdir $DIR/$tdir
23862         for count in $(seq 2 $MDSCOUNT); do
23863                 test_300s_helper $count
23864         done
23865 }
23866 run_test 300s "test lfs mkdir -c without -i"
23867
23868 test_300t() {
23869         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
23870                 skip "need MDS 2.14.55 or later"
23871         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
23872
23873         local testdir="$DIR/$tdir/striped_dir"
23874         local dir1=$testdir/dir1
23875         local dir2=$testdir/dir2
23876
23877         mkdir -p $testdir
23878
23879         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
23880                 error "failed to set default stripe count for $testdir"
23881
23882         mkdir $dir1
23883         local stripe_count=$($LFS getdirstripe -c $dir1)
23884
23885         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
23886
23887         local max_count=$((MDSCOUNT - 1))
23888         local mdts=$(comma_list $(mdts_nodes))
23889
23890         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
23891         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
23892
23893         mkdir $dir2
23894         stripe_count=$($LFS getdirstripe -c $dir2)
23895
23896         (( $stripe_count == $max_count )) || error "wrong stripe count"
23897 }
23898 run_test 300t "test max_mdt_stripecount"
23899
23900 prepare_remote_file() {
23901         mkdir $DIR/$tdir/src_dir ||
23902                 error "create remote source failed"
23903
23904         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23905                  error "cp to remote source failed"
23906         touch $DIR/$tdir/src_dir/a
23907
23908         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23909                 error "create remote target dir failed"
23910
23911         touch $DIR/$tdir/tgt_dir/b
23912
23913         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23914                 error "rename dir cross MDT failed!"
23915
23916         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23917                 error "src_child still exists after rename"
23918
23919         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23920                 error "missing file(a) after rename"
23921
23922         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23923                 error "diff after rename"
23924 }
23925
23926 test_310a() {
23927         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23929
23930         local remote_file=$DIR/$tdir/tgt_dir/b
23931
23932         mkdir -p $DIR/$tdir
23933
23934         prepare_remote_file || error "prepare remote file failed"
23935
23936         #open-unlink file
23937         $OPENUNLINK $remote_file $remote_file ||
23938                 error "openunlink $remote_file failed"
23939         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23940 }
23941 run_test 310a "open unlink remote file"
23942
23943 test_310b() {
23944         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23946
23947         local remote_file=$DIR/$tdir/tgt_dir/b
23948
23949         mkdir -p $DIR/$tdir
23950
23951         prepare_remote_file || error "prepare remote file failed"
23952
23953         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23954         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23955         $CHECKSTAT -t file $remote_file || error "check file failed"
23956 }
23957 run_test 310b "unlink remote file with multiple links while open"
23958
23959 test_310c() {
23960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23961         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23962
23963         local remote_file=$DIR/$tdir/tgt_dir/b
23964
23965         mkdir -p $DIR/$tdir
23966
23967         prepare_remote_file || error "prepare remote file failed"
23968
23969         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23970         multiop_bg_pause $remote_file O_uc ||
23971                         error "mulitop failed for remote file"
23972         MULTIPID=$!
23973         $MULTIOP $DIR/$tfile Ouc
23974         kill -USR1 $MULTIPID
23975         wait $MULTIPID
23976 }
23977 run_test 310c "open-unlink remote file with multiple links"
23978
23979 #LU-4825
23980 test_311() {
23981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23982         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23983         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23984                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23985         remote_mds_nodsh && skip "remote MDS with nodsh"
23986
23987         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23988         local mdts=$(comma_list $(mdts_nodes))
23989
23990         mkdir -p $DIR/$tdir
23991         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23992         createmany -o $DIR/$tdir/$tfile. 1000
23993
23994         # statfs data is not real time, let's just calculate it
23995         old_iused=$((old_iused + 1000))
23996
23997         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23998                         osp.*OST0000*MDT0000.create_count")
23999         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24000                                 osp.*OST0000*MDT0000.max_create_count")
24001         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24002
24003         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24004         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24005         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24006
24007         unlinkmany $DIR/$tdir/$tfile. 1000
24008
24009         do_nodes $mdts "$LCTL set_param -n \
24010                         osp.*OST0000*.max_create_count=$max_count"
24011         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24012                 do_nodes $mdts "$LCTL set_param -n \
24013                                 osp.*OST0000*.create_count=$count"
24014         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24015                         grep "=0" && error "create_count is zero"
24016
24017         local new_iused
24018         for i in $(seq 120); do
24019                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24020                 # system may be too busy to destroy all objs in time, use
24021                 # a somewhat small value to not fail autotest
24022                 [ $((old_iused - new_iused)) -gt 400 ] && break
24023                 sleep 1
24024         done
24025
24026         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24027         [ $((old_iused - new_iused)) -gt 400 ] ||
24028                 error "objs not destroyed after unlink"
24029 }
24030 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24031
24032 zfs_oid_to_objid()
24033 {
24034         local ost=$1
24035         local objid=$2
24036
24037         local vdevdir=$(dirname $(facet_vdevice $ost))
24038         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24039         local zfs_zapid=$(do_facet $ost $cmd |
24040                           grep -w "/O/0/d$((objid%32))" -C 5 |
24041                           awk '/Object/{getline; print $1}')
24042         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24043                           awk "/$objid = /"'{printf $3}')
24044
24045         echo $zfs_objid
24046 }
24047
24048 zfs_object_blksz() {
24049         local ost=$1
24050         local objid=$2
24051
24052         local vdevdir=$(dirname $(facet_vdevice $ost))
24053         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24054         local blksz=$(do_facet $ost $cmd $objid |
24055                       awk '/dblk/{getline; printf $4}')
24056
24057         case "${blksz: -1}" in
24058                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24059                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24060                 *) ;;
24061         esac
24062
24063         echo $blksz
24064 }
24065
24066 test_312() { # LU-4856
24067         remote_ost_nodsh && skip "remote OST with nodsh"
24068         [ "$ost1_FSTYPE" = "zfs" ] ||
24069                 skip_env "the test only applies to zfs"
24070
24071         local max_blksz=$(do_facet ost1 \
24072                           $ZFS get -p recordsize $(facet_device ost1) |
24073                           awk '!/VALUE/{print $3}')
24074
24075         # to make life a little bit easier
24076         $LFS mkdir -c 1 -i 0 $DIR/$tdir
24077         $LFS setstripe -c 1 -i 0 $DIR/$tdir
24078
24079         local tf=$DIR/$tdir/$tfile
24080         touch $tf
24081         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24082
24083         # Get ZFS object id
24084         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24085         # block size change by sequential overwrite
24086         local bs
24087
24088         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24089                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24090
24091                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
24092                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
24093         done
24094         rm -f $tf
24095
24096         # block size change by sequential append write
24097         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24098         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24099         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24100         local count
24101
24102         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24103                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24104                         oflag=sync conv=notrunc
24105
24106                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
24107                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
24108                         error "blksz error, actual $blksz, " \
24109                                 "expected: 2 * $count * $PAGE_SIZE"
24110         done
24111         rm -f $tf
24112
24113         # random write
24114         touch $tf
24115         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
24116         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
24117
24118         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24119         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24120         [ $blksz -eq $PAGE_SIZE ] ||
24121                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24122
24123         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24124         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24125         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
24126
24127         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24128         blksz=$(zfs_object_blksz ost1 $zfs_objid)
24129         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
24130 }
24131 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24132
24133 test_313() {
24134         remote_ost_nodsh && skip "remote OST with nodsh"
24135
24136         local file=$DIR/$tfile
24137
24138         rm -f $file
24139         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24140
24141         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24142         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24143         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24144                 error "write should failed"
24145         do_facet ost1 "$LCTL set_param fail_loc=0"
24146         rm -f $file
24147 }
24148 run_test 313 "io should fail after last_rcvd update fail"
24149
24150 test_314() {
24151         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24152
24153         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24154         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24155         rm -f $DIR/$tfile
24156         wait_delete_completed
24157         do_facet ost1 "$LCTL set_param fail_loc=0"
24158 }
24159 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24160
24161 test_315() { # LU-618
24162         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24163
24164         local file=$DIR/$tfile
24165         rm -f $file
24166
24167         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24168                 error "multiop file write failed"
24169         $MULTIOP $file oO_RDONLY:r4063232_c &
24170         PID=$!
24171
24172         sleep 2
24173
24174         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24175         kill -USR1 $PID
24176
24177         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24178         rm -f $file
24179 }
24180 run_test 315 "read should be accounted"
24181
24182 test_316() {
24183         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24184         large_xattr_enabled || skip "ea_inode feature disabled"
24185
24186         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24187         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24188         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24189         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24190
24191         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24192 }
24193 run_test 316 "lfs migrate of file with large_xattr enabled"
24194
24195 test_317() {
24196         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24197                 skip "Need MDS version at least 2.11.53"
24198         if [ "$ost1_FSTYPE" == "zfs" ]; then
24199                 skip "LU-10370: no implementation for ZFS"
24200         fi
24201
24202         local trunc_sz
24203         local grant_blk_size
24204
24205         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24206                         awk '/grant_block_size:/ { print $2; exit; }')
24207         #
24208         # Create File of size 5M. Truncate it to below size's and verify
24209         # blocks count.
24210         #
24211         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24212                 error "Create file $DIR/$tfile failed"
24213         stack_trap "rm -f $DIR/$tfile" EXIT
24214
24215         for trunc_sz in 2097152 4097 4000 509 0; do
24216                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24217                         error "truncate $tfile to $trunc_sz failed"
24218                 local sz=$(stat --format=%s $DIR/$tfile)
24219                 local blk=$(stat --format=%b $DIR/$tfile)
24220                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24221                                      grant_blk_size) * 8))
24222
24223                 if [[ $blk -ne $trunc_blk ]]; then
24224                         $(which stat) $DIR/$tfile
24225                         error "Expected Block $trunc_blk got $blk for $tfile"
24226                 fi
24227
24228                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24229                         error "Expected Size $trunc_sz got $sz for $tfile"
24230         done
24231
24232         #
24233         # sparse file test
24234         # Create file with a hole and write actual 65536 bytes which aligned
24235         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24236         #
24237         local bs=65536
24238         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24239                 error "Create file : $DIR/$tfile"
24240
24241         #
24242         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24243         # blocks. The block count must drop to 8.
24244         #
24245         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24246                 ((bs - grant_blk_size) + 1)))
24247         $TRUNCATE $DIR/$tfile $trunc_sz ||
24248                 error "truncate $tfile to $trunc_sz failed"
24249
24250         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24251         sz=$(stat --format=%s $DIR/$tfile)
24252         blk=$(stat --format=%b $DIR/$tfile)
24253
24254         if [[ $blk -ne $trunc_bsz ]]; then
24255                 $(which stat) $DIR/$tfile
24256                 error "Expected Block $trunc_bsz got $blk for $tfile"
24257         fi
24258
24259         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24260                 error "Expected Size $trunc_sz got $sz for $tfile"
24261 }
24262 run_test 317 "Verify blocks get correctly update after truncate"
24263
24264 test_318() {
24265         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24266         local old_max_active=$($LCTL get_param -n \
24267                             ${llite_name}.max_read_ahead_async_active \
24268                             2>/dev/null)
24269
24270         $LCTL set_param llite.*.max_read_ahead_async_active=256
24271         local max_active=$($LCTL get_param -n \
24272                            ${llite_name}.max_read_ahead_async_active \
24273                            2>/dev/null)
24274         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24275
24276         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24277                 error "set max_read_ahead_async_active should succeed"
24278
24279         $LCTL set_param llite.*.max_read_ahead_async_active=512
24280         max_active=$($LCTL get_param -n \
24281                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24282         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24283
24284         # restore @max_active
24285         [ $old_max_active -ne 0 ] && $LCTL set_param \
24286                 llite.*.max_read_ahead_async_active=$old_max_active
24287
24288         local old_threshold=$($LCTL get_param -n \
24289                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24290         local max_per_file_mb=$($LCTL get_param -n \
24291                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24292
24293         local invalid=$(($max_per_file_mb + 1))
24294         $LCTL set_param \
24295                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24296                         && error "set $invalid should fail"
24297
24298         local valid=$(($invalid - 1))
24299         $LCTL set_param \
24300                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24301                         error "set $valid should succeed"
24302         local threshold=$($LCTL get_param -n \
24303                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24304         [ $threshold -eq $valid ] || error \
24305                 "expect threshold $valid got $threshold"
24306         $LCTL set_param \
24307                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24308 }
24309 run_test 318 "Verify async readahead tunables"
24310
24311 test_319() {
24312         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24313
24314         local before=$(date +%s)
24315         local evict
24316         local mdir=$DIR/$tdir
24317         local file=$mdir/xxx
24318
24319         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24320         touch $file
24321
24322 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24323         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24324         $LFS migrate -m1 $mdir &
24325
24326         sleep 1
24327         dd if=$file of=/dev/null
24328         wait
24329         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24330           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24331
24332         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24333 }
24334 run_test 319 "lost lease lock on migrate error"
24335
24336 test_398a() { # LU-4198
24337         local ost1_imp=$(get_osc_import_name client ost1)
24338         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24339                          cut -d'.' -f2)
24340
24341         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24342         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24343
24344         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24345         # request a new lock on client
24346         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24347
24348         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24349         #local lock_count=$($LCTL get_param -n \
24350         #                  ldlm.namespaces.$imp_name.lru_size)
24351         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24352
24353         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24354
24355         # no lock cached, should use lockless DIO and not enqueue new lock
24356         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
24357                 conv=notrunc ||
24358                 error "dio write failed"
24359         lock_count=$($LCTL get_param -n \
24360                      ldlm.namespaces.$imp_name.lru_size)
24361         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24362
24363         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24364
24365         # no lock cached, should use locked DIO append
24366         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
24367                 conv=notrunc || error "DIO append failed"
24368         lock_count=$($LCTL get_param -n \
24369                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
24370         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
24371 }
24372 run_test 398a "direct IO should cancel lock otherwise lockless"
24373
24374 test_398b() { # LU-4198
24375         which fio || skip_env "no fio installed"
24376         $LFS setstripe -c -1 $DIR/$tfile
24377
24378         local size=12
24379         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24380
24381         local njobs=4
24382         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24383         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24384                 --numjobs=$njobs --fallocate=none \
24385                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24386                 --filename=$DIR/$tfile &
24387         bg_pid=$!
24388
24389         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24390         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24391                 --numjobs=$njobs --fallocate=none \
24392                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24393                 --filename=$DIR/$tfile || true
24394         wait $bg_pid
24395
24396         rm -f $DIR/$tfile
24397 }
24398 run_test 398b "DIO and buffer IO race"
24399
24400 test_398c() { # LU-4198
24401         local ost1_imp=$(get_osc_import_name client ost1)
24402         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24403                          cut -d'.' -f2)
24404
24405         which fio || skip_env "no fio installed"
24406
24407         saved_debug=$($LCTL get_param -n debug)
24408         $LCTL set_param debug=0
24409
24410         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24411         ((size /= 1024)) # by megabytes
24412         ((size /= 2)) # write half of the OST at most
24413         [ $size -gt 40 ] && size=40 #reduce test time anyway
24414
24415         $LFS setstripe -c 1 $DIR/$tfile
24416
24417         # it seems like ldiskfs reserves more space than necessary if the
24418         # writing blocks are not mapped, so it extends the file firstly
24419         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24420         cancel_lru_locks osc
24421
24422         # clear and verify rpc_stats later
24423         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24424
24425         local njobs=4
24426         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24427         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24428                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24429                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24430                 --filename=$DIR/$tfile
24431         [ $? -eq 0 ] || error "fio write error"
24432
24433         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24434                 error "Locks were requested while doing AIO"
24435
24436         # get the percentage of 1-page I/O
24437         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24438                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24439                 awk '{print $7}')
24440         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24441
24442         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24443         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24444                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24445                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24446                 --filename=$DIR/$tfile
24447         [ $? -eq 0 ] || error "fio mixed read write error"
24448
24449         echo "AIO with large block size ${size}M"
24450         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24451                 --numjobs=1 --fallocate=none --ioengine=libaio \
24452                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24453                 --filename=$DIR/$tfile
24454         [ $? -eq 0 ] || error "fio large block size failed"
24455
24456         rm -f $DIR/$tfile
24457         $LCTL set_param debug="$saved_debug"
24458 }
24459 run_test 398c "run fio to test AIO"
24460
24461 test_398d() { #  LU-13846
24462         which aiocp || skip_env "no aiocp installed"
24463         local aio_file=$DIR/$tfile.aio
24464
24465         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24466
24467         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24468         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24469         stack_trap "rm -f $DIR/$tfile $aio_file"
24470
24471         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24472
24473         # make sure we don't crash and fail properly
24474         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24475                 error "aio not aligned with PAGE SIZE should fail"
24476
24477         rm -f $DIR/$tfile $aio_file
24478 }
24479 run_test 398d "run aiocp to verify block size > stripe size"
24480
24481 test_398e() {
24482         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24483         touch $DIR/$tfile.new
24484         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24485 }
24486 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24487
24488 test_398f() { #  LU-14687
24489         which aiocp || skip_env "no aiocp installed"
24490         local aio_file=$DIR/$tfile.aio
24491
24492         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24493
24494         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24495         stack_trap "rm -f $DIR/$tfile $aio_file"
24496
24497         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24498         $LCTL set_param fail_loc=0x1418
24499         # make sure we don't crash and fail properly
24500         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24501                 error "aio with page allocation failure succeeded"
24502         $LCTL set_param fail_loc=0
24503         diff $DIR/$tfile $aio_file
24504         [[ $? != 0 ]] || error "no diff after failed aiocp"
24505 }
24506 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24507
24508 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24509 # stripe and i/o size must be > stripe size
24510 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24511 # single RPC in flight.  This test shows async DIO submission is working by
24512 # showing multiple RPCs in flight.
24513 test_398g() { #  LU-13798
24514         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24515
24516         # We need to do some i/o first to acquire enough grant to put our RPCs
24517         # in flight; otherwise a new connection may not have enough grant
24518         # available
24519         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24520                 error "parallel dio failed"
24521         stack_trap "rm -f $DIR/$tfile"
24522
24523         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24524         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24525         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24526         stack_trap "$LCTL set_param -n $pages_per_rpc"
24527
24528         # Recreate file so it's empty
24529         rm -f $DIR/$tfile
24530         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24531         #Pause rpc completion to guarantee we see multiple rpcs in flight
24532         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24533         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24534         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24535
24536         # Clear rpc stats
24537         $LCTL set_param osc.*.rpc_stats=c
24538
24539         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24540                 error "parallel dio failed"
24541         stack_trap "rm -f $DIR/$tfile"
24542
24543         $LCTL get_param osc.*-OST0000-*.rpc_stats
24544         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24545                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24546                 grep "8:" | awk '{print $8}')
24547         # We look at the "8 rpcs in flight" field, and verify A) it is present
24548         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24549         # as expected for an 8M DIO to a file with 1M stripes.
24550         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24551
24552         # Verify turning off parallel dio works as expected
24553         # Clear rpc stats
24554         $LCTL set_param osc.*.rpc_stats=c
24555         $LCTL set_param llite.*.parallel_dio=0
24556         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24557
24558         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24559                 error "dio with parallel dio disabled failed"
24560
24561         # Ideally, we would see only one RPC in flight here, but there is an
24562         # unavoidable race between i/o completion and RPC in flight counting,
24563         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24564         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24565         # So instead we just verify it's always < 8.
24566         $LCTL get_param osc.*-OST0000-*.rpc_stats
24567         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24568                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24569                 grep '^$' -B1 | grep . | awk '{print $1}')
24570         [ $ret != "8:" ] ||
24571                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24572 }
24573 run_test 398g "verify parallel dio async RPC submission"
24574
24575 test_398h() { #  LU-13798
24576         local dio_file=$DIR/$tfile.dio
24577
24578         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24579
24580         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24581         stack_trap "rm -f $DIR/$tfile $dio_file"
24582
24583         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24584                 error "parallel dio failed"
24585         diff $DIR/$tfile $dio_file
24586         [[ $? == 0 ]] || error "file diff after aiocp"
24587 }
24588 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24589
24590 test_398i() { #  LU-13798
24591         local dio_file=$DIR/$tfile.dio
24592
24593         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24594
24595         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24596         stack_trap "rm -f $DIR/$tfile $dio_file"
24597
24598         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24599         $LCTL set_param fail_loc=0x1418
24600         # make sure we don't crash and fail properly
24601         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24602                 error "parallel dio page allocation failure succeeded"
24603         diff $DIR/$tfile $dio_file
24604         [[ $? != 0 ]] || error "no diff after failed aiocp"
24605 }
24606 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24607
24608 test_398j() { #  LU-13798
24609         # Stripe size > RPC size but less than i/o size tests split across
24610         # stripes and RPCs for individual i/o op
24611         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24612
24613         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24614         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24615         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24616         stack_trap "$LCTL set_param -n $pages_per_rpc"
24617
24618         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24619                 error "parallel dio write failed"
24620         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24621
24622         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24623                 error "parallel dio read failed"
24624         diff $DIR/$tfile $DIR/$tfile.2
24625         [[ $? == 0 ]] || error "file diff after parallel dio read"
24626 }
24627 run_test 398j "test parallel dio where stripe size > rpc_size"
24628
24629 test_398k() { #  LU-13798
24630         wait_delete_completed
24631         wait_mds_ost_sync
24632
24633         # 4 stripe file; we will cause out of space on OST0
24634         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24635
24636         # Fill OST0 (if it's not too large)
24637         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24638                    head -n1)
24639         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24640                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24641         fi
24642         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24643         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24644                 error "dd should fill OST0"
24645         stack_trap "rm -f $DIR/$tfile.1"
24646
24647         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24648         err=$?
24649
24650         ls -la $DIR/$tfile
24651         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24652                 error "file is not 0 bytes in size"
24653
24654         # dd above should not succeed, but don't error until here so we can
24655         # get debug info above
24656         [[ $err != 0 ]] ||
24657                 error "parallel dio write with enospc succeeded"
24658         stack_trap "rm -f $DIR/$tfile"
24659 }
24660 run_test 398k "test enospc on first stripe"
24661
24662 test_398l() { #  LU-13798
24663         wait_delete_completed
24664         wait_mds_ost_sync
24665
24666         # 4 stripe file; we will cause out of space on OST0
24667         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24668         # happens on the second i/o chunk we issue
24669         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24670
24671         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24672         stack_trap "rm -f $DIR/$tfile"
24673
24674         # Fill OST0 (if it's not too large)
24675         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24676                    head -n1)
24677         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24678                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24679         fi
24680         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24681         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24682                 error "dd should fill OST0"
24683         stack_trap "rm -f $DIR/$tfile.1"
24684
24685         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24686         err=$?
24687         stack_trap "rm -f $DIR/$tfile.2"
24688
24689         # Check that short write completed as expected
24690         ls -la $DIR/$tfile.2
24691         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24692                 error "file is not 1M in size"
24693
24694         # dd above should not succeed, but don't error until here so we can
24695         # get debug info above
24696         [[ $err != 0 ]] ||
24697                 error "parallel dio write with enospc succeeded"
24698
24699         # Truncate source file to same length as output file and diff them
24700         $TRUNCATE $DIR/$tfile 1048576
24701         diff $DIR/$tfile $DIR/$tfile.2
24702         [[ $? == 0 ]] || error "data incorrect after short write"
24703 }
24704 run_test 398l "test enospc on intermediate stripe/RPC"
24705
24706 test_398m() { #  LU-13798
24707         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24708
24709         # Set up failure on OST0, the first stripe:
24710         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24711         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24712         # So this fail_val specifies OST0
24713         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24714         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24715
24716         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24717                 error "parallel dio write with failure on first stripe succeeded"
24718         stack_trap "rm -f $DIR/$tfile"
24719         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24720
24721         # Place data in file for read
24722         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24723                 error "parallel dio write failed"
24724
24725         # Fail read on OST0, first stripe
24726         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24727         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24728         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24729                 error "parallel dio read with error on first stripe succeeded"
24730         rm -f $DIR/$tfile.2
24731         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24732
24733         # Switch to testing on OST1, second stripe
24734         # Clear file contents, maintain striping
24735         echo > $DIR/$tfile
24736         # Set up failure on OST1, second stripe:
24737         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24738         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24739
24740         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24741                 error "parallel dio write with failure on first stripe succeeded"
24742         stack_trap "rm -f $DIR/$tfile"
24743         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24744
24745         # Place data in file for read
24746         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24747                 error "parallel dio write failed"
24748
24749         # Fail read on OST1, second stripe
24750         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24751         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24752         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24753                 error "parallel dio read with error on first stripe succeeded"
24754         rm -f $DIR/$tfile.2
24755         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24756 }
24757 run_test 398m "test RPC failures with parallel dio"
24758
24759 # Parallel submission of DIO should not cause problems for append, but it's
24760 # important to verify.
24761 test_398n() { #  LU-13798
24762         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24763
24764         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24765                 error "dd to create source file failed"
24766         stack_trap "rm -f $DIR/$tfile"
24767
24768         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24769                 error "parallel dio write with failure on second stripe succeeded"
24770         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24771         diff $DIR/$tfile $DIR/$tfile.1
24772         [[ $? == 0 ]] || error "data incorrect after append"
24773
24774 }
24775 run_test 398n "test append with parallel DIO"
24776
24777 test_fake_rw() {
24778         local read_write=$1
24779         if [ "$read_write" = "write" ]; then
24780                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24781         elif [ "$read_write" = "read" ]; then
24782                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24783         else
24784                 error "argument error"
24785         fi
24786
24787         # turn off debug for performance testing
24788         local saved_debug=$($LCTL get_param -n debug)
24789         $LCTL set_param debug=0
24790
24791         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24792
24793         # get ost1 size - $FSNAME-OST0000
24794         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24795         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24796         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24797
24798         if [ "$read_write" = "read" ]; then
24799                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24800         fi
24801
24802         local start_time=$(date +%s.%N)
24803         $dd_cmd bs=1M count=$blocks oflag=sync ||
24804                 error "real dd $read_write error"
24805         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24806
24807         if [ "$read_write" = "write" ]; then
24808                 rm -f $DIR/$tfile
24809         fi
24810
24811         # define OBD_FAIL_OST_FAKE_RW           0x238
24812         do_facet ost1 $LCTL set_param fail_loc=0x238
24813
24814         local start_time=$(date +%s.%N)
24815         $dd_cmd bs=1M count=$blocks oflag=sync ||
24816                 error "fake dd $read_write error"
24817         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24818
24819         if [ "$read_write" = "write" ]; then
24820                 # verify file size
24821                 cancel_lru_locks osc
24822                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24823                         error "$tfile size not $blocks MB"
24824         fi
24825         do_facet ost1 $LCTL set_param fail_loc=0
24826
24827         echo "fake $read_write $duration_fake vs. normal $read_write" \
24828                 "$duration in seconds"
24829         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24830                 error_not_in_vm "fake write is slower"
24831
24832         $LCTL set_param -n debug="$saved_debug"
24833         rm -f $DIR/$tfile
24834 }
24835 test_399a() { # LU-7655 for OST fake write
24836         remote_ost_nodsh && skip "remote OST with nodsh"
24837
24838         test_fake_rw write
24839 }
24840 run_test 399a "fake write should not be slower than normal write"
24841
24842 test_399b() { # LU-8726 for OST fake read
24843         remote_ost_nodsh && skip "remote OST with nodsh"
24844         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24845                 skip_env "ldiskfs only test"
24846         fi
24847
24848         test_fake_rw read
24849 }
24850 run_test 399b "fake read should not be slower than normal read"
24851
24852 test_400a() { # LU-1606, was conf-sanity test_74
24853         if ! which $CC > /dev/null 2>&1; then
24854                 skip_env "$CC is not installed"
24855         fi
24856
24857         local extra_flags=''
24858         local out=$TMP/$tfile
24859         local prefix=/usr/include/lustre
24860         local prog
24861
24862         # Oleg removes c files in his test rig so test if any c files exist
24863         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24864                 skip_env "Needed c test files are missing"
24865
24866         if ! [[ -d $prefix ]]; then
24867                 # Assume we're running in tree and fixup the include path.
24868                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24869                 extra_flags+=" -L$LUSTRE/utils/.lib"
24870         fi
24871
24872         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24873                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24874                         error "client api broken"
24875         done
24876         rm -f $out
24877 }
24878 run_test 400a "Lustre client api program can compile and link"
24879
24880 test_400b() { # LU-1606, LU-5011
24881         local header
24882         local out=$TMP/$tfile
24883         local prefix=/usr/include/linux/lustre
24884
24885         # We use a hard coded prefix so that this test will not fail
24886         # when run in tree. There are headers in lustre/include/lustre/
24887         # that are not packaged (like lustre_idl.h) and have more
24888         # complicated include dependencies (like config.h and lnet/types.h).
24889         # Since this test about correct packaging we just skip them when
24890         # they don't exist (see below) rather than try to fixup cppflags.
24891
24892         if ! which $CC > /dev/null 2>&1; then
24893                 skip_env "$CC is not installed"
24894         fi
24895
24896         for header in $prefix/*.h; do
24897                 if ! [[ -f "$header" ]]; then
24898                         continue
24899                 fi
24900
24901                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24902                         continue # lustre_ioctl.h is internal header
24903                 fi
24904
24905                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24906                         error "cannot compile '$header'"
24907         done
24908         rm -f $out
24909 }
24910 run_test 400b "packaged headers can be compiled"
24911
24912 test_401a() { #LU-7437
24913         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24914         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24915
24916         #count the number of parameters by "list_param -R"
24917         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24918         #count the number of parameters by listing proc files
24919         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24920         echo "proc_dirs='$proc_dirs'"
24921         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24922         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24923                       sort -u | wc -l)
24924
24925         [ $params -eq $procs ] ||
24926                 error "found $params parameters vs. $procs proc files"
24927
24928         # test the list_param -D option only returns directories
24929         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24930         #count the number of parameters by listing proc directories
24931         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24932                 sort -u | wc -l)
24933
24934         [ $params -eq $procs ] ||
24935                 error "found $params parameters vs. $procs proc files"
24936 }
24937 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24938
24939 test_401b() {
24940         # jobid_var may not allow arbitrary values, so use jobid_name
24941         # if available
24942         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24943                 local testname=jobid_name tmp='testing%p'
24944         else
24945                 local testname=jobid_var tmp=testing
24946         fi
24947
24948         local save=$($LCTL get_param -n $testname)
24949
24950         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24951                 error "no error returned when setting bad parameters"
24952
24953         local jobid_new=$($LCTL get_param -n foe $testname baz)
24954         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24955
24956         $LCTL set_param -n fog=bam $testname=$save bat=fog
24957         local jobid_old=$($LCTL get_param -n foe $testname bag)
24958         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24959 }
24960 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24961
24962 test_401c() {
24963         # jobid_var may not allow arbitrary values, so use jobid_name
24964         # if available
24965         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24966                 local testname=jobid_name
24967         else
24968                 local testname=jobid_var
24969         fi
24970
24971         local jobid_var_old=$($LCTL get_param -n $testname)
24972         local jobid_var_new
24973
24974         $LCTL set_param $testname= &&
24975                 error "no error returned for 'set_param a='"
24976
24977         jobid_var_new=$($LCTL get_param -n $testname)
24978         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24979                 error "$testname was changed by setting without value"
24980
24981         $LCTL set_param $testname &&
24982                 error "no error returned for 'set_param a'"
24983
24984         jobid_var_new=$($LCTL get_param -n $testname)
24985         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24986                 error "$testname was changed by setting without value"
24987 }
24988 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24989
24990 test_401d() {
24991         # jobid_var may not allow arbitrary values, so use jobid_name
24992         # if available
24993         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24994                 local testname=jobid_name new_value='foo=bar%p'
24995         else
24996                 local testname=jobid_var new_valuie=foo=bar
24997         fi
24998
24999         local jobid_var_old=$($LCTL get_param -n $testname)
25000         local jobid_var_new
25001
25002         $LCTL set_param $testname=$new_value ||
25003                 error "'set_param a=b' did not accept a value containing '='"
25004
25005         jobid_var_new=$($LCTL get_param -n $testname)
25006         [[ "$jobid_var_new" == "$new_value" ]] ||
25007                 error "'set_param a=b' failed on a value containing '='"
25008
25009         # Reset the $testname to test the other format
25010         $LCTL set_param $testname=$jobid_var_old
25011         jobid_var_new=$($LCTL get_param -n $testname)
25012         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25013                 error "failed to reset $testname"
25014
25015         $LCTL set_param $testname $new_value ||
25016                 error "'set_param a b' did not accept a value containing '='"
25017
25018         jobid_var_new=$($LCTL get_param -n $testname)
25019         [[ "$jobid_var_new" == "$new_value" ]] ||
25020                 error "'set_param a b' failed on a value containing '='"
25021
25022         $LCTL set_param $testname $jobid_var_old
25023         jobid_var_new=$($LCTL get_param -n $testname)
25024         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25025                 error "failed to reset $testname"
25026 }
25027 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25028
25029 test_401e() { # LU-14779
25030         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25031                 error "lctl list_param MGC* failed"
25032         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25033         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25034                 error "lctl get_param lru_size failed"
25035 }
25036 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25037
25038 test_402() {
25039         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25040         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25041                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25042         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25043                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25044                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25045         remote_mds_nodsh && skip "remote MDS with nodsh"
25046
25047         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25048 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25049         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25050         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25051                 echo "Touch failed - OK"
25052 }
25053 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25054
25055 test_403() {
25056         local file1=$DIR/$tfile.1
25057         local file2=$DIR/$tfile.2
25058         local tfile=$TMP/$tfile
25059
25060         rm -f $file1 $file2 $tfile
25061
25062         touch $file1
25063         ln $file1 $file2
25064
25065         # 30 sec OBD_TIMEOUT in ll_getattr()
25066         # right before populating st_nlink
25067         $LCTL set_param fail_loc=0x80001409
25068         stat -c %h $file1 > $tfile &
25069
25070         # create an alias, drop all locks and reclaim the dentry
25071         < $file2
25072         cancel_lru_locks mdc
25073         cancel_lru_locks osc
25074         sysctl -w vm.drop_caches=2
25075
25076         wait
25077
25078         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25079
25080         rm -f $tfile $file1 $file2
25081 }
25082 run_test 403 "i_nlink should not drop to zero due to aliasing"
25083
25084 test_404() { # LU-6601
25085         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25086                 skip "Need server version newer than 2.8.52"
25087         remote_mds_nodsh && skip "remote MDS with nodsh"
25088
25089         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25090                 awk '/osp .*-osc-MDT/ { print $4}')
25091
25092         local osp
25093         for osp in $mosps; do
25094                 echo "Deactivate: " $osp
25095                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25096                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25097                         awk -vp=$osp '$4 == p { print $2 }')
25098                 [ $stat = IN ] || {
25099                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25100                         error "deactivate error"
25101                 }
25102                 echo "Activate: " $osp
25103                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25104                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25105                         awk -vp=$osp '$4 == p { print $2 }')
25106                 [ $stat = UP ] || {
25107                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25108                         error "activate error"
25109                 }
25110         done
25111 }
25112 run_test 404 "validate manual {de}activated works properly for OSPs"
25113
25114 test_405() {
25115         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25116         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25117                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25118                         skip "Layout swap lock is not supported"
25119
25120         check_swap_layouts_support
25121         check_swap_layout_no_dom $DIR
25122
25123         test_mkdir $DIR/$tdir
25124         swap_lock_test -d $DIR/$tdir ||
25125                 error "One layout swap locked test failed"
25126 }
25127 run_test 405 "Various layout swap lock tests"
25128
25129 test_406() {
25130         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25131         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25132         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25134         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25135                 skip "Need MDS version at least 2.8.50"
25136
25137         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25138         local test_pool=$TESTNAME
25139
25140         pool_add $test_pool || error "pool_add failed"
25141         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25142                 error "pool_add_targets failed"
25143
25144         save_layout_restore_at_exit $MOUNT
25145
25146         # parent set default stripe count only, child will stripe from both
25147         # parent and fs default
25148         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25149                 error "setstripe $MOUNT failed"
25150         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25151         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25152         for i in $(seq 10); do
25153                 local f=$DIR/$tdir/$tfile.$i
25154                 touch $f || error "touch failed"
25155                 local count=$($LFS getstripe -c $f)
25156                 [ $count -eq $OSTCOUNT ] ||
25157                         error "$f stripe count $count != $OSTCOUNT"
25158                 local offset=$($LFS getstripe -i $f)
25159                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25160                 local size=$($LFS getstripe -S $f)
25161                 [ $size -eq $((def_stripe_size * 2)) ] ||
25162                         error "$f stripe size $size != $((def_stripe_size * 2))"
25163                 local pool=$($LFS getstripe -p $f)
25164                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25165         done
25166
25167         # change fs default striping, delete parent default striping, now child
25168         # will stripe from new fs default striping only
25169         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25170                 error "change $MOUNT default stripe failed"
25171         $LFS setstripe -c 0 $DIR/$tdir ||
25172                 error "delete $tdir default stripe failed"
25173         for i in $(seq 11 20); do
25174                 local f=$DIR/$tdir/$tfile.$i
25175                 touch $f || error "touch $f failed"
25176                 local count=$($LFS getstripe -c $f)
25177                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25178                 local offset=$($LFS getstripe -i $f)
25179                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25180                 local size=$($LFS getstripe -S $f)
25181                 [ $size -eq $def_stripe_size ] ||
25182                         error "$f stripe size $size != $def_stripe_size"
25183                 local pool=$($LFS getstripe -p $f)
25184                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25185         done
25186
25187         unlinkmany $DIR/$tdir/$tfile. 1 20
25188
25189         local f=$DIR/$tdir/$tfile
25190         pool_remove_all_targets $test_pool $f
25191         pool_remove $test_pool $f
25192 }
25193 run_test 406 "DNE support fs default striping"
25194
25195 test_407() {
25196         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25197         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25198                 skip "Need MDS version at least 2.8.55"
25199         remote_mds_nodsh && skip "remote MDS with nodsh"
25200
25201         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25202                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25203         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25204                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25205         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25206
25207         #define OBD_FAIL_DT_TXN_STOP    0x2019
25208         for idx in $(seq $MDSCOUNT); do
25209                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25210         done
25211         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25212         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25213                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25214         true
25215 }
25216 run_test 407 "transaction fail should cause operation fail"
25217
25218 test_408() {
25219         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25220
25221         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25222         lctl set_param fail_loc=0x8000040a
25223         # let ll_prepare_partial_page() fail
25224         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25225
25226         rm -f $DIR/$tfile
25227
25228         # create at least 100 unused inodes so that
25229         # shrink_icache_memory(0) should not return 0
25230         touch $DIR/$tfile-{0..100}
25231         rm -f $DIR/$tfile-{0..100}
25232         sync
25233
25234         echo 2 > /proc/sys/vm/drop_caches
25235 }
25236 run_test 408 "drop_caches should not hang due to page leaks"
25237
25238 test_409()
25239 {
25240         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25241
25242         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25243         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25244         touch $DIR/$tdir/guard || error "(2) Fail to create"
25245
25246         local PREFIX=$(str_repeat 'A' 128)
25247         echo "Create 1K hard links start at $(date)"
25248         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25249                 error "(3) Fail to hard link"
25250
25251         echo "Links count should be right although linkEA overflow"
25252         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25253         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25254         [ $linkcount -eq 1001 ] ||
25255                 error "(5) Unexpected hard links count: $linkcount"
25256
25257         echo "List all links start at $(date)"
25258         ls -l $DIR/$tdir/foo > /dev/null ||
25259                 error "(6) Fail to list $DIR/$tdir/foo"
25260
25261         echo "Unlink hard links start at $(date)"
25262         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25263                 error "(7) Fail to unlink"
25264         echo "Unlink hard links finished at $(date)"
25265 }
25266 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25267
25268 test_410()
25269 {
25270         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25271                 skip "Need client version at least 2.9.59"
25272         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25273                 skip "Need MODULES build"
25274
25275         # Create a file, and stat it from the kernel
25276         local testfile=$DIR/$tfile
25277         touch $testfile
25278
25279         local run_id=$RANDOM
25280         local my_ino=$(stat --format "%i" $testfile)
25281
25282         # Try to insert the module. This will always fail as the
25283         # module is designed to not be inserted.
25284         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25285             &> /dev/null
25286
25287         # Anything but success is a test failure
25288         dmesg | grep -q \
25289             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25290             error "no inode match"
25291 }
25292 run_test 410 "Test inode number returned from kernel thread"
25293
25294 cleanup_test411_cgroup() {
25295         trap 0
25296         rmdir "$1"
25297 }
25298
25299 test_411() {
25300         local cg_basedir=/sys/fs/cgroup/memory
25301         # LU-9966
25302         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25303                 skip "no setup for cgroup"
25304
25305         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25306                 error "test file creation failed"
25307         cancel_lru_locks osc
25308
25309         # Create a very small memory cgroup to force a slab allocation error
25310         local cgdir=$cg_basedir/osc_slab_alloc
25311         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25312         trap "cleanup_test411_cgroup $cgdir" EXIT
25313         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25314         echo 1M > $cgdir/memory.limit_in_bytes
25315
25316         # Should not LBUG, just be killed by oom-killer
25317         # dd will return 0 even allocation failure in some environment.
25318         # So don't check return value
25319         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25320         cleanup_test411_cgroup $cgdir
25321
25322         return 0
25323 }
25324 run_test 411 "Slab allocation error with cgroup does not LBUG"
25325
25326 test_412() {
25327         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25328         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25329                 skip "Need server version at least 2.10.55"
25330
25331         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25332                 error "mkdir failed"
25333         $LFS getdirstripe $DIR/$tdir
25334         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25335         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25336                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25337         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25338         [ $stripe_count -eq 2 ] ||
25339                 error "expect 2 get $stripe_count"
25340
25341         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25342
25343         local index
25344         local index2
25345
25346         # subdirs should be on the same MDT as parent
25347         for i in $(seq 0 $((MDSCOUNT - 1))); do
25348                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25349                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25350                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25351                 (( index == i )) || error "mdt$i/sub on MDT$index"
25352         done
25353
25354         # stripe offset -1, ditto
25355         for i in {1..10}; do
25356                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25357                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25358                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25359                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25360                 (( index == index2 )) ||
25361                         error "qos$i on MDT$index, sub on MDT$index2"
25362         done
25363
25364         local testdir=$DIR/$tdir/inherit
25365
25366         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25367         # inherit 2 levels
25368         for i in 1 2; do
25369                 testdir=$testdir/s$i
25370                 mkdir $testdir || error "mkdir $testdir failed"
25371                 index=$($LFS getstripe -m $testdir)
25372                 (( index == 1 )) ||
25373                         error "$testdir on MDT$index"
25374         done
25375
25376         # not inherit any more
25377         testdir=$testdir/s3
25378         mkdir $testdir || error "mkdir $testdir failed"
25379         getfattr -d -m dmv $testdir | grep dmv &&
25380                 error "default LMV set on $testdir" || true
25381 }
25382 run_test 412 "mkdir on specific MDTs"
25383
25384 generate_uneven_mdts() {
25385         local threshold=$1
25386         local lmv_qos_maxage
25387         local lod_qos_maxage
25388         local ffree
25389         local bavail
25390         local max
25391         local min
25392         local max_index
25393         local min_index
25394         local tmp
25395         local i
25396
25397         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25398         $LCTL set_param lmv.*.qos_maxage=1
25399         stack_trap "$LCTL set_param \
25400                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25401         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25402                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25403         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25404                 lod.*.mdt_qos_maxage=1
25405         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25406                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25407
25408         echo
25409         echo "Check for uneven MDTs: "
25410
25411         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25412         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25413         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25414
25415         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25416         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25417         max_index=0
25418         min_index=0
25419         for ((i = 1; i < ${#ffree[@]}; i++)); do
25420                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25421                 if [ $tmp -gt $max ]; then
25422                         max=$tmp
25423                         max_index=$i
25424                 fi
25425                 if [ $tmp -lt $min ]; then
25426                         min=$tmp
25427                         min_index=$i
25428                 fi
25429         done
25430
25431         (( ${ffree[min_index]} > 0 )) ||
25432                 skip "no free files in MDT$min_index"
25433         (( ${ffree[min_index]} < 10000000 )) ||
25434                 skip "too many free files in MDT$min_index"
25435
25436         # Check if we need to generate uneven MDTs
25437         local diff=$(((max - min) * 100 / min))
25438         local testdir=$DIR/$tdir-fillmdt
25439         local start
25440
25441         mkdir -p $testdir
25442
25443         i=0
25444         while (( diff < threshold )); do
25445                 # generate uneven MDTs, create till $threshold% diff
25446                 echo -n "weight diff=$diff% must be > $threshold% ..."
25447                 echo "Fill MDT$min_index with 1000 files: loop $i"
25448                 testdir=$DIR/$tdir-fillmdt/$i
25449                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25450                         error "mkdir $testdir failed"
25451                 $LFS setstripe -E 1M -L mdt $testdir ||
25452                         error "setstripe $testdir failed"
25453                 start=$SECONDS
25454                 for F in f.{0..999}; do
25455                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25456                                 /dev/null 2>&1 || error "dd $F failed"
25457                 done
25458
25459                 # wait for QOS to update
25460                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25461
25462                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25463                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25464                 max=$(((${ffree[max_index]} >> 8) *
25465                         (${bavail[max_index]} * bsize >> 16)))
25466                 min=$(((${ffree[min_index]} >> 8) *
25467                         (${bavail[min_index]} * bsize >> 16)))
25468                 diff=$(((max - min) * 100 / min))
25469                 i=$((i + 1))
25470         done
25471
25472         echo "MDT filesfree available: ${ffree[*]}"
25473         echo "MDT blocks available: ${bavail[*]}"
25474         echo "weight diff=$diff%"
25475 }
25476
25477 test_qos_mkdir() {
25478         local mkdir_cmd=$1
25479         local stripe_count=$2
25480         local mdts=$(comma_list $(mdts_nodes))
25481
25482         local testdir
25483         local lmv_qos_prio_free
25484         local lmv_qos_threshold_rr
25485         local lmv_qos_maxage
25486         local lod_qos_prio_free
25487         local lod_qos_threshold_rr
25488         local lod_qos_maxage
25489         local count
25490         local i
25491
25492         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25493         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25494         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25495                 head -n1)
25496         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25497         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25498         stack_trap "$LCTL set_param \
25499                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25500         stack_trap "$LCTL set_param \
25501                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25502         stack_trap "$LCTL set_param \
25503                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25504
25505         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25506                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25507         lod_qos_prio_free=${lod_qos_prio_free%%%}
25508         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25509                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25510         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25511         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25512                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25513         stack_trap "do_nodes $mdts $LCTL set_param \
25514                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25515         stack_trap "do_nodes $mdts $LCTL set_param \
25516                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25517         stack_trap "do_nodes $mdts $LCTL set_param \
25518                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25519
25520         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25521         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25522
25523         testdir=$DIR/$tdir-s$stripe_count/rr
25524
25525         local stripe_index=$($LFS getstripe -m $testdir)
25526         local test_mkdir_rr=true
25527
25528         getfattr -d -m dmv -e hex $testdir | grep dmv
25529         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25530                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25531                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25532                         test_mkdir_rr=false
25533         fi
25534
25535         echo
25536         $test_mkdir_rr &&
25537                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25538                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25539
25540         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25541         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25542                 eval $mkdir_cmd $testdir/subdir$i ||
25543                         error "$mkdir_cmd subdir$i failed"
25544         done
25545
25546         for (( i = 0; i < $MDSCOUNT; i++ )); do
25547                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25548                 echo "$count directories created on MDT$i"
25549                 if $test_mkdir_rr; then
25550                         (( $count == 100 )) ||
25551                                 error "subdirs are not evenly distributed"
25552                 elif (( $i == $stripe_index )); then
25553                         (( $count == 100 * MDSCOUNT )) ||
25554                                 error "$count subdirs created on MDT$i"
25555                 else
25556                         (( $count == 0 )) ||
25557                                 error "$count subdirs created on MDT$i"
25558                 fi
25559
25560                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25561                         count=$($LFS getdirstripe $testdir/* |
25562                                 grep -c -P "^\s+$i\t")
25563                         echo "$count stripes created on MDT$i"
25564                         # deviation should < 5% of average
25565                         (( $count >= 95 * stripe_count &&
25566                            $count <= 105 * stripe_count)) ||
25567                                 error "stripes are not evenly distributed"
25568                 fi
25569         done
25570
25571         echo
25572         echo "Check for uneven MDTs: "
25573
25574         local ffree
25575         local bavail
25576         local max
25577         local min
25578         local max_index
25579         local min_index
25580         local tmp
25581
25582         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25583         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25584         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25585
25586         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25587         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25588         max_index=0
25589         min_index=0
25590         for ((i = 1; i < ${#ffree[@]}; i++)); do
25591                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25592                 if [ $tmp -gt $max ]; then
25593                         max=$tmp
25594                         max_index=$i
25595                 fi
25596                 if [ $tmp -lt $min ]; then
25597                         min=$tmp
25598                         min_index=$i
25599                 fi
25600         done
25601
25602         (( ${ffree[min_index]} > 0 )) ||
25603                 skip "no free files in MDT$min_index"
25604         (( ${ffree[min_index]} < 10000000 )) ||
25605                 skip "too many free files in MDT$min_index"
25606
25607         echo "MDT filesfree available: ${ffree[*]}"
25608         echo "MDT blocks available: ${bavail[*]}"
25609         echo "weight diff=$(((max - min) * 100 / min))%"
25610         echo
25611         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25612
25613         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25614         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25615         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25616         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25617         # decrease statfs age, so that it can be updated in time
25618         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25619         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25620
25621         sleep 1
25622
25623         testdir=$DIR/$tdir-s$stripe_count/qos
25624         local num=200
25625
25626         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25627         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25628                 eval $mkdir_cmd $testdir/subdir$i ||
25629                         error "$mkdir_cmd subdir$i failed"
25630         done
25631
25632         max=0
25633         for (( i = 0; i < $MDSCOUNT; i++ )); do
25634                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25635                 (( count > max )) && max=$count
25636                 echo "$count directories created on MDT$i"
25637         done
25638
25639         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25640
25641         # D-value should > 10% of averge
25642         (( max - min > num / 10 )) ||
25643                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25644
25645         # ditto for stripes
25646         if (( stripe_count > 1 )); then
25647                 max=0
25648                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25649                         count=$($LFS getdirstripe $testdir/* |
25650                                 grep -c -P "^\s+$i\t")
25651                         (( count > max )) && max=$count
25652                         echo "$count stripes created on MDT$i"
25653                 done
25654
25655                 min=$($LFS getdirstripe $testdir/* |
25656                         grep -c -P "^\s+$min_index\t")
25657                 (( max - min > num * stripe_count / 10 )) ||
25658                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25659         fi
25660 }
25661
25662 most_full_mdt() {
25663         local ffree
25664         local bavail
25665         local bsize
25666         local min
25667         local min_index
25668         local tmp
25669
25670         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25671         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25672         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25673
25674         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25675         min_index=0
25676         for ((i = 1; i < ${#ffree[@]}; i++)); do
25677                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25678                 (( tmp < min )) && min=$tmp && min_index=$i
25679         done
25680
25681         echo -n $min_index
25682 }
25683
25684 test_413a() {
25685         [ $MDSCOUNT -lt 2 ] &&
25686                 skip "We need at least 2 MDTs for this test"
25687
25688         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25689                 skip "Need server version at least 2.12.52"
25690
25691         local stripe_count
25692
25693         generate_uneven_mdts 100
25694         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25695                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25696                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25697                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25698                         error "mkdir failed"
25699                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25700         done
25701 }
25702 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25703
25704 test_413b() {
25705         [ $MDSCOUNT -lt 2 ] &&
25706                 skip "We need at least 2 MDTs for this test"
25707
25708         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25709                 skip "Need server version at least 2.12.52"
25710
25711         local testdir
25712         local stripe_count
25713
25714         generate_uneven_mdts 100
25715         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25716                 testdir=$DIR/$tdir-s$stripe_count
25717                 mkdir $testdir || error "mkdir $testdir failed"
25718                 mkdir $testdir/rr || error "mkdir rr failed"
25719                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25720                         error "mkdir qos failed"
25721                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25722                         $testdir/rr || error "setdirstripe rr failed"
25723                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25724                         error "setdirstripe failed"
25725                 test_qos_mkdir "mkdir" $stripe_count
25726         done
25727 }
25728 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25729
25730 test_413c() {
25731         (( $MDSCOUNT >= 2 )) ||
25732                 skip "We need at least 2 MDTs for this test"
25733
25734         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25735                 skip "Need server version at least 2.14.51"
25736
25737         local testdir
25738         local inherit
25739         local inherit_rr
25740
25741         testdir=$DIR/${tdir}-s1
25742         mkdir $testdir || error "mkdir $testdir failed"
25743         mkdir $testdir/rr || error "mkdir rr failed"
25744         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25745         # default max_inherit is -1, default max_inherit_rr is 0
25746         $LFS setdirstripe -D -c 1 $testdir/rr ||
25747                 error "setdirstripe rr failed"
25748         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25749                 error "setdirstripe qos failed"
25750         test_qos_mkdir "mkdir" 1
25751
25752         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25753         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25754         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25755         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25756         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25757
25758         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25759         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25760         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25761         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25762         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25763         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25764         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25765                 error "level2 shouldn't have default LMV" || true
25766 }
25767 run_test 413c "mkdir with default LMV max inherit rr"
25768
25769 test_413d() {
25770         (( MDSCOUNT >= 2 )) ||
25771                 skip "We need at least 2 MDTs for this test"
25772
25773         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25774                 skip "Need server version at least 2.14.51"
25775
25776         local lmv_qos_threshold_rr
25777
25778         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25779                 head -n1)
25780         stack_trap "$LCTL set_param \
25781                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25782
25783         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25784         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25785         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25786                 error "$tdir shouldn't have default LMV"
25787         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25788                 error "mkdir sub failed"
25789
25790         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25791
25792         (( count == 100 )) || error "$count subdirs on MDT0"
25793 }
25794 run_test 413d "inherit ROOT default LMV"
25795
25796 test_413e() {
25797         (( MDSCOUNT >= 2 )) ||
25798                 skip "We need at least 2 MDTs for this test"
25799         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25800                 skip "Need server version at least 2.14.55"
25801
25802         local testdir=$DIR/$tdir
25803         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
25804         local max_inherit
25805         local sub_max_inherit
25806
25807         mkdir -p $testdir || error "failed to create $testdir"
25808
25809         # set default max-inherit to -1 if stripe count is 0 or 1
25810         $LFS setdirstripe -D -c 1 $testdir ||
25811                 error "failed to set default LMV"
25812         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25813         (( max_inherit == -1 )) ||
25814                 error "wrong max_inherit value $max_inherit"
25815
25816         # set default max_inherit to a fixed value if stripe count is not 0 or 1
25817         $LFS setdirstripe -D -c -1 $testdir ||
25818                 error "failed to set default LMV"
25819         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25820         (( max_inherit > 0 )) ||
25821                 error "wrong max_inherit value $max_inherit"
25822
25823         # and the subdir will decrease the max_inherit by 1
25824         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
25825         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
25826         (( sub_max_inherit == max_inherit - 1)) ||
25827                 error "wrong max-inherit of subdir $sub_max_inherit"
25828
25829         # check specified --max-inherit and warning message
25830         stack_trap "rm -f $tmpfile"
25831         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
25832                 error "failed to set default LMV"
25833         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
25834         (( max_inherit == -1 )) ||
25835                 error "wrong max_inherit value $max_inherit"
25836
25837         # check the warning messages
25838         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
25839                 error "failed to detect warning string"
25840         fi
25841 }
25842 run_test 413e "check default max-inherit value"
25843
25844 test_413f() {
25845         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
25846
25847         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
25848                 skip "Need server version at least 2.14.55"
25849
25850         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
25851                 error "dump $DIR default LMV failed"
25852         stack_trap "setfattr --restore=$TMP/dmv.ea"
25853
25854         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
25855                 error "set $DIR default LMV failed"
25856
25857         local testdir=$DIR/$tdir
25858
25859         local count
25860         local inherit
25861         local inherit_rr
25862
25863         for i in $(seq 3); do
25864                 mkdir $testdir || error "mkdir $testdir failed"
25865                 count=$($LFS getdirstripe -D -c $testdir)
25866                 (( count == 1 )) ||
25867                         error "$testdir default LMV count mismatch $count != 1"
25868                 inherit=$($LFS getdirstripe -D -X $testdir)
25869                 (( inherit == 3 - i )) ||
25870                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
25871                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
25872                 (( inherit_rr == 3 - i )) ||
25873                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
25874                 testdir=$testdir/sub
25875         done
25876
25877         mkdir $testdir || error "mkdir $testdir failed"
25878         count=$($LFS getdirstripe -D -c $testdir)
25879         (( count == 0 )) ||
25880                 error "$testdir default LMV count not zero: $count"
25881 }
25882 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
25883
25884 test_413z() {
25885         local pids=""
25886         local subdir
25887         local pid
25888
25889         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25890                 unlinkmany $subdir/f. 1000 &
25891                 pids="$pids $!"
25892         done
25893
25894         for pid in $pids; do
25895                 wait $pid
25896         done
25897 }
25898 run_test 413z "413 test cleanup"
25899
25900 test_414() {
25901 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25902         $LCTL set_param fail_loc=0x80000521
25903         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25904         rm -f $DIR/$tfile
25905 }
25906 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25907
25908 test_415() {
25909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25910         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25911                 skip "Need server version at least 2.11.52"
25912
25913         # LU-11102
25914         local total
25915         local setattr_pid
25916         local start_time
25917         local end_time
25918         local duration
25919
25920         total=500
25921         # this test may be slow on ZFS
25922         [ "$mds1_FSTYPE" == "zfs" ] && total=50
25923
25924         # though this test is designed for striped directory, let's test normal
25925         # directory too since lock is always saved as CoS lock.
25926         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25927         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25928
25929         (
25930                 while true; do
25931                         touch $DIR/$tdir
25932                 done
25933         ) &
25934         setattr_pid=$!
25935
25936         start_time=$(date +%s)
25937         for i in $(seq $total); do
25938                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25939                         > /dev/null
25940         done
25941         end_time=$(date +%s)
25942         duration=$((end_time - start_time))
25943
25944         kill -9 $setattr_pid
25945
25946         echo "rename $total files took $duration sec"
25947         [ $duration -lt 100 ] || error "rename took $duration sec"
25948 }
25949 run_test 415 "lock revoke is not missing"
25950
25951 test_416() {
25952         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25953                 skip "Need server version at least 2.11.55"
25954
25955         # define OBD_FAIL_OSD_TXN_START    0x19a
25956         do_facet mds1 lctl set_param fail_loc=0x19a
25957
25958         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25959
25960         true
25961 }
25962 run_test 416 "transaction start failure won't cause system hung"
25963
25964 cleanup_417() {
25965         trap 0
25966         do_nodes $(comma_list $(mdts_nodes)) \
25967                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25968         do_nodes $(comma_list $(mdts_nodes)) \
25969                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25970         do_nodes $(comma_list $(mdts_nodes)) \
25971                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25972 }
25973
25974 test_417() {
25975         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25976         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25977                 skip "Need MDS version at least 2.11.56"
25978
25979         trap cleanup_417 RETURN EXIT
25980
25981         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25982         do_nodes $(comma_list $(mdts_nodes)) \
25983                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25984         $LFS migrate -m 0 $DIR/$tdir.1 &&
25985                 error "migrate dir $tdir.1 should fail"
25986
25987         do_nodes $(comma_list $(mdts_nodes)) \
25988                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25989         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25990                 error "create remote dir $tdir.2 should fail"
25991
25992         do_nodes $(comma_list $(mdts_nodes)) \
25993                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25994         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25995                 error "create striped dir $tdir.3 should fail"
25996         true
25997 }
25998 run_test 417 "disable remote dir, striped dir and dir migration"
25999
26000 # Checks that the outputs of df [-i] and lfs df [-i] match
26001 #
26002 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26003 check_lfs_df() {
26004         local dir=$2
26005         local inodes
26006         local df_out
26007         local lfs_df_out
26008         local count
26009         local passed=false
26010
26011         # blocks or inodes
26012         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26013
26014         for count in {1..100}; do
26015                 do_nodes "$CLIENTS" \
26016                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26017                 sync; sleep 0.2
26018
26019                 # read the lines of interest
26020                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26021                         error "df $inodes $dir | tail -n +2 failed"
26022                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26023                         error "lfs df $inodes $dir | grep summary: failed"
26024
26025                 # skip first substrings of each output as they are different
26026                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26027                 # compare the two outputs
26028                 passed=true
26029                 #  skip "available" on MDT until LU-13997 is fixed.
26030                 #for i in {1..5}; do
26031                 for i in 1 2 4 5; do
26032                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26033                 done
26034                 $passed && break
26035         done
26036
26037         if ! $passed; then
26038                 df -P $inodes $dir
26039                 echo
26040                 lfs df $inodes $dir
26041                 error "df and lfs df $1 output mismatch: "      \
26042                       "df ${inodes}: ${df_out[*]}, "            \
26043                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26044         fi
26045 }
26046
26047 test_418() {
26048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26049
26050         local dir=$DIR/$tdir
26051         local numfiles=$((RANDOM % 4096 + 2))
26052         local numblocks=$((RANDOM % 256 + 1))
26053
26054         wait_delete_completed
26055         test_mkdir $dir
26056
26057         # check block output
26058         check_lfs_df blocks $dir
26059         # check inode output
26060         check_lfs_df inodes $dir
26061
26062         # create a single file and retest
26063         echo "Creating a single file and testing"
26064         createmany -o $dir/$tfile- 1 &>/dev/null ||
26065                 error "creating 1 file in $dir failed"
26066         check_lfs_df blocks $dir
26067         check_lfs_df inodes $dir
26068
26069         # create a random number of files
26070         echo "Creating $((numfiles - 1)) files and testing"
26071         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26072                 error "creating $((numfiles - 1)) files in $dir failed"
26073
26074         # write a random number of blocks to the first test file
26075         echo "Writing $numblocks 4K blocks and testing"
26076         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26077                 count=$numblocks &>/dev/null ||
26078                 error "dd to $dir/${tfile}-0 failed"
26079
26080         # retest
26081         check_lfs_df blocks $dir
26082         check_lfs_df inodes $dir
26083
26084         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26085                 error "unlinking $numfiles files in $dir failed"
26086 }
26087 run_test 418 "df and lfs df outputs match"
26088
26089 test_419()
26090 {
26091         local dir=$DIR/$tdir
26092
26093         mkdir -p $dir
26094         touch $dir/file
26095
26096         cancel_lru_locks mdc
26097
26098         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26099         $LCTL set_param fail_loc=0x1410
26100         cat $dir/file
26101         $LCTL set_param fail_loc=0
26102         rm -rf $dir
26103 }
26104 run_test 419 "Verify open file by name doesn't crash kernel"
26105
26106 test_420()
26107 {
26108         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26109                 skip "Need MDS version at least 2.12.53"
26110
26111         local SAVE_UMASK=$(umask)
26112         local dir=$DIR/$tdir
26113         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26114
26115         mkdir -p $dir
26116         umask 0000
26117         mkdir -m03777 $dir/testdir
26118         ls -dn $dir/testdir
26119         # Need to remove trailing '.' when SELinux is enabled
26120         local dirperms=$(ls -dn $dir/testdir |
26121                          awk '{ sub(/\.$/, "", $1); print $1}')
26122         [ $dirperms == "drwxrwsrwt" ] ||
26123                 error "incorrect perms on $dir/testdir"
26124
26125         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26126                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26127         ls -n $dir/testdir/testfile
26128         local fileperms=$(ls -n $dir/testdir/testfile |
26129                           awk '{ sub(/\.$/, "", $1); print $1}')
26130         [ $fileperms == "-rwxr-xr-x" ] ||
26131                 error "incorrect perms on $dir/testdir/testfile"
26132
26133         umask $SAVE_UMASK
26134 }
26135 run_test 420 "clear SGID bit on non-directories for non-members"
26136
26137 test_421a() {
26138         local cnt
26139         local fid1
26140         local fid2
26141
26142         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26143                 skip "Need MDS version at least 2.12.54"
26144
26145         test_mkdir $DIR/$tdir
26146         createmany -o $DIR/$tdir/f 3
26147         cnt=$(ls -1 $DIR/$tdir | wc -l)
26148         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26149
26150         fid1=$(lfs path2fid $DIR/$tdir/f1)
26151         fid2=$(lfs path2fid $DIR/$tdir/f2)
26152         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26153
26154         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26155         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26156
26157         cnt=$(ls -1 $DIR/$tdir | wc -l)
26158         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26159
26160         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26161         createmany -o $DIR/$tdir/f 3
26162         cnt=$(ls -1 $DIR/$tdir | wc -l)
26163         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26164
26165         fid1=$(lfs path2fid $DIR/$tdir/f1)
26166         fid2=$(lfs path2fid $DIR/$tdir/f2)
26167         echo "remove using fsname $FSNAME"
26168         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26169
26170         cnt=$(ls -1 $DIR/$tdir | wc -l)
26171         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26172 }
26173 run_test 421a "simple rm by fid"
26174
26175 test_421b() {
26176         local cnt
26177         local FID1
26178         local FID2
26179
26180         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26181                 skip "Need MDS version at least 2.12.54"
26182
26183         test_mkdir $DIR/$tdir
26184         createmany -o $DIR/$tdir/f 3
26185         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26186         MULTIPID=$!
26187
26188         FID1=$(lfs path2fid $DIR/$tdir/f1)
26189         FID2=$(lfs path2fid $DIR/$tdir/f2)
26190         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26191
26192         kill -USR1 $MULTIPID
26193         wait
26194
26195         cnt=$(ls $DIR/$tdir | wc -l)
26196         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26197 }
26198 run_test 421b "rm by fid on open file"
26199
26200 test_421c() {
26201         local cnt
26202         local FIDS
26203
26204         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26205                 skip "Need MDS version at least 2.12.54"
26206
26207         test_mkdir $DIR/$tdir
26208         createmany -o $DIR/$tdir/f 3
26209         touch $DIR/$tdir/$tfile
26210         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26211         cnt=$(ls -1 $DIR/$tdir | wc -l)
26212         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26213
26214         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26215         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26216
26217         cnt=$(ls $DIR/$tdir | wc -l)
26218         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26219 }
26220 run_test 421c "rm by fid against hardlinked files"
26221
26222 test_421d() {
26223         local cnt
26224         local FIDS
26225
26226         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26227                 skip "Need MDS version at least 2.12.54"
26228
26229         test_mkdir $DIR/$tdir
26230         createmany -o $DIR/$tdir/f 4097
26231         cnt=$(ls -1 $DIR/$tdir | wc -l)
26232         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26233
26234         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26235         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26236
26237         cnt=$(ls $DIR/$tdir | wc -l)
26238         rm -rf $DIR/$tdir
26239         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26240 }
26241 run_test 421d "rmfid en masse"
26242
26243 test_421e() {
26244         local cnt
26245         local FID
26246
26247         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26248         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26249                 skip "Need MDS version at least 2.12.54"
26250
26251         mkdir -p $DIR/$tdir
26252         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26253         createmany -o $DIR/$tdir/striped_dir/f 512
26254         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26255         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26256
26257         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26258                 sed "s/[/][^:]*://g")
26259         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26260
26261         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26262         rm -rf $DIR/$tdir
26263         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26264 }
26265 run_test 421e "rmfid in DNE"
26266
26267 test_421f() {
26268         local cnt
26269         local FID
26270
26271         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26272                 skip "Need MDS version at least 2.12.54"
26273
26274         test_mkdir $DIR/$tdir
26275         touch $DIR/$tdir/f
26276         cnt=$(ls -1 $DIR/$tdir | wc -l)
26277         [ $cnt != 1 ] && error "unexpected #files: $cnt"
26278
26279         FID=$(lfs path2fid $DIR/$tdir/f)
26280         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26281         # rmfid should fail
26282         cnt=$(ls -1 $DIR/$tdir | wc -l)
26283         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26284
26285         chmod a+rw $DIR/$tdir
26286         ls -la $DIR/$tdir
26287         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26288         # rmfid should fail
26289         cnt=$(ls -1 $DIR/$tdir | wc -l)
26290         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26291
26292         rm -f $DIR/$tdir/f
26293         $RUNAS touch $DIR/$tdir/f
26294         FID=$(lfs path2fid $DIR/$tdir/f)
26295         echo "rmfid as root"
26296         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26297         cnt=$(ls -1 $DIR/$tdir | wc -l)
26298         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26299
26300         rm -f $DIR/$tdir/f
26301         $RUNAS touch $DIR/$tdir/f
26302         cnt=$(ls -1 $DIR/$tdir | wc -l)
26303         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26304         FID=$(lfs path2fid $DIR/$tdir/f)
26305         # rmfid w/o user_fid2path mount option should fail
26306         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26307         cnt=$(ls -1 $DIR/$tdir | wc -l)
26308         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26309
26310         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26311         stack_trap "rmdir $tmpdir"
26312         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26313                 error "failed to mount client'"
26314         stack_trap "umount_client $tmpdir"
26315
26316         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26317         # rmfid should succeed
26318         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26319         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26320
26321         # rmfid shouldn't allow to remove files due to dir's permission
26322         chmod a+rwx $tmpdir/$tdir
26323         touch $tmpdir/$tdir/f
26324         ls -la $tmpdir/$tdir
26325         FID=$(lfs path2fid $tmpdir/$tdir/f)
26326         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26327         return 0
26328 }
26329 run_test 421f "rmfid checks permissions"
26330
26331 test_421g() {
26332         local cnt
26333         local FIDS
26334
26335         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26336         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26337                 skip "Need MDS version at least 2.12.54"
26338
26339         mkdir -p $DIR/$tdir
26340         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26341         createmany -o $DIR/$tdir/striped_dir/f 512
26342         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26343         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26344
26345         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26346                 sed "s/[/][^:]*://g")
26347
26348         rm -f $DIR/$tdir/striped_dir/f1*
26349         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26350         removed=$((512 - cnt))
26351
26352         # few files have been just removed, so we expect
26353         # rmfid to fail on their fids
26354         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26355         [ $removed != $errors ] && error "$errors != $removed"
26356
26357         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26358         rm -rf $DIR/$tdir
26359         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26360 }
26361 run_test 421g "rmfid to return errors properly"
26362
26363 test_422() {
26364         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26365         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26366         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26367         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26368         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26369
26370         local amc=$(at_max_get client)
26371         local amo=$(at_max_get mds1)
26372         local timeout=`lctl get_param -n timeout`
26373
26374         at_max_set 0 client
26375         at_max_set 0 mds1
26376
26377 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26378         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26379                         fail_val=$(((2*timeout + 10)*1000))
26380         touch $DIR/$tdir/d3/file &
26381         sleep 2
26382 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26383         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26384                         fail_val=$((2*timeout + 5))
26385         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26386         local pid=$!
26387         sleep 1
26388         kill -9 $pid
26389         sleep $((2 * timeout))
26390         echo kill $pid
26391         kill -9 $pid
26392         lctl mark touch
26393         touch $DIR/$tdir/d2/file3
26394         touch $DIR/$tdir/d2/file4
26395         touch $DIR/$tdir/d2/file5
26396
26397         wait
26398         at_max_set $amc client
26399         at_max_set $amo mds1
26400
26401         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26402         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26403                 error "Watchdog is always throttled"
26404 }
26405 run_test 422 "kill a process with RPC in progress"
26406
26407 stat_test() {
26408     df -h $MOUNT &
26409     df -h $MOUNT &
26410     df -h $MOUNT &
26411     df -h $MOUNT &
26412     df -h $MOUNT &
26413     df -h $MOUNT &
26414 }
26415
26416 test_423() {
26417     local _stats
26418     # ensure statfs cache is expired
26419     sleep 2;
26420
26421     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26422     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26423
26424     return 0
26425 }
26426 run_test 423 "statfs should return a right data"
26427
26428 test_424() {
26429 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26430         $LCTL set_param fail_loc=0x80000522
26431         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26432         rm -f $DIR/$tfile
26433 }
26434 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26435
26436 test_425() {
26437         test_mkdir -c -1 $DIR/$tdir
26438         $LFS setstripe -c -1 $DIR/$tdir
26439
26440         lru_resize_disable "" 100
26441         stack_trap "lru_resize_enable" EXIT
26442
26443         sleep 5
26444
26445         for i in $(seq $((MDSCOUNT * 125))); do
26446                 local t=$DIR/$tdir/$tfile_$i
26447
26448                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26449                         error_noexit "Create file $t"
26450         done
26451         stack_trap "rm -rf $DIR/$tdir" EXIT
26452
26453         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26454                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26455                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26456
26457                 [ $lock_count -le $lru_size ] ||
26458                         error "osc lock count $lock_count > lru size $lru_size"
26459         done
26460
26461         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26462                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26463                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26464
26465                 [ $lock_count -le $lru_size ] ||
26466                         error "mdc lock count $lock_count > lru size $lru_size"
26467         done
26468 }
26469 run_test 425 "lock count should not exceed lru size"
26470
26471 test_426() {
26472         splice-test -r $DIR/$tfile
26473         splice-test -rd $DIR/$tfile
26474         splice-test $DIR/$tfile
26475         splice-test -d $DIR/$tfile
26476 }
26477 run_test 426 "splice test on Lustre"
26478
26479 test_427() {
26480         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26481         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26482                 skip "Need MDS version at least 2.12.4"
26483         local log
26484
26485         mkdir $DIR/$tdir
26486         mkdir $DIR/$tdir/1
26487         mkdir $DIR/$tdir/2
26488         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26489         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26490
26491         $LFS getdirstripe $DIR/$tdir/1/dir
26492
26493         #first setfattr for creating updatelog
26494         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26495
26496 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26497         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26498         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26499         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26500
26501         sleep 2
26502         fail mds2
26503         wait_recovery_complete mds2 $((2*TIMEOUT))
26504
26505         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26506         echo $log | grep "get update log failed" &&
26507                 error "update log corruption is detected" || true
26508 }
26509 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26510
26511 test_428() {
26512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26513         local cache_limit=$CACHE_MAX
26514
26515         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26516         $LCTL set_param -n llite.*.max_cached_mb=64
26517
26518         mkdir $DIR/$tdir
26519         $LFS setstripe -c 1 $DIR/$tdir
26520         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26521         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26522         #test write
26523         for f in $(seq 4); do
26524                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26525         done
26526         wait
26527
26528         cancel_lru_locks osc
26529         # Test read
26530         for f in $(seq 4); do
26531                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26532         done
26533         wait
26534 }
26535 run_test 428 "large block size IO should not hang"
26536
26537 test_429() { # LU-7915 / LU-10948
26538         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26539         local testfile=$DIR/$tfile
26540         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26541         local new_flag=1
26542         local first_rpc
26543         local second_rpc
26544         local third_rpc
26545
26546         $LCTL get_param $ll_opencache_threshold_count ||
26547                 skip "client does not have opencache parameter"
26548
26549         set_opencache $new_flag
26550         stack_trap "restore_opencache"
26551         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26552                 error "enable opencache failed"
26553         touch $testfile
26554         # drop MDC DLM locks
26555         cancel_lru_locks mdc
26556         # clear MDC RPC stats counters
26557         $LCTL set_param $mdc_rpcstats=clear
26558
26559         # According to the current implementation, we need to run 3 times
26560         # open & close file to verify if opencache is enabled correctly.
26561         # 1st, RPCs are sent for lookup/open and open handle is released on
26562         #      close finally.
26563         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26564         #      so open handle won't be released thereafter.
26565         # 3rd, No RPC is sent out.
26566         $MULTIOP $testfile oc || error "multiop failed"
26567         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26568         echo "1st: $first_rpc RPCs in flight"
26569
26570         $MULTIOP $testfile oc || error "multiop failed"
26571         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26572         echo "2nd: $second_rpc RPCs in flight"
26573
26574         $MULTIOP $testfile oc || error "multiop failed"
26575         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26576         echo "3rd: $third_rpc RPCs in flight"
26577
26578         #verify no MDC RPC is sent
26579         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26580 }
26581 run_test 429 "verify if opencache flag on client side does work"
26582
26583 lseek_test_430() {
26584         local offset
26585         local file=$1
26586
26587         # data at [200K, 400K)
26588         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26589                 error "256K->512K dd fails"
26590         # data at [2M, 3M)
26591         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26592                 error "2M->3M dd fails"
26593         # data at [4M, 5M)
26594         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26595                 error "4M->5M dd fails"
26596         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26597         # start at first component hole #1
26598         printf "Seeking hole from 1000 ... "
26599         offset=$(lseek_test -l 1000 $file)
26600         echo $offset
26601         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26602         printf "Seeking data from 1000 ... "
26603         offset=$(lseek_test -d 1000 $file)
26604         echo $offset
26605         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26606
26607         # start at first component data block
26608         printf "Seeking hole from 300000 ... "
26609         offset=$(lseek_test -l 300000 $file)
26610         echo $offset
26611         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26612         printf "Seeking data from 300000 ... "
26613         offset=$(lseek_test -d 300000 $file)
26614         echo $offset
26615         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26616
26617         # start at the first component but beyond end of object size
26618         printf "Seeking hole from 1000000 ... "
26619         offset=$(lseek_test -l 1000000 $file)
26620         echo $offset
26621         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26622         printf "Seeking data from 1000000 ... "
26623         offset=$(lseek_test -d 1000000 $file)
26624         echo $offset
26625         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26626
26627         # start at second component stripe 2 (empty file)
26628         printf "Seeking hole from 1500000 ... "
26629         offset=$(lseek_test -l 1500000 $file)
26630         echo $offset
26631         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26632         printf "Seeking data from 1500000 ... "
26633         offset=$(lseek_test -d 1500000 $file)
26634         echo $offset
26635         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26636
26637         # start at second component stripe 1 (all data)
26638         printf "Seeking hole from 3000000 ... "
26639         offset=$(lseek_test -l 3000000 $file)
26640         echo $offset
26641         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26642         printf "Seeking data from 3000000 ... "
26643         offset=$(lseek_test -d 3000000 $file)
26644         echo $offset
26645         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26646
26647         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26648                 error "2nd dd fails"
26649         echo "Add data block at 640K...1280K"
26650
26651         # start at before new data block, in hole
26652         printf "Seeking hole from 600000 ... "
26653         offset=$(lseek_test -l 600000 $file)
26654         echo $offset
26655         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26656         printf "Seeking data from 600000 ... "
26657         offset=$(lseek_test -d 600000 $file)
26658         echo $offset
26659         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26660
26661         # start at the first component new data block
26662         printf "Seeking hole from 1000000 ... "
26663         offset=$(lseek_test -l 1000000 $file)
26664         echo $offset
26665         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26666         printf "Seeking data from 1000000 ... "
26667         offset=$(lseek_test -d 1000000 $file)
26668         echo $offset
26669         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26670
26671         # start at second component stripe 2, new data
26672         printf "Seeking hole from 1200000 ... "
26673         offset=$(lseek_test -l 1200000 $file)
26674         echo $offset
26675         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26676         printf "Seeking data from 1200000 ... "
26677         offset=$(lseek_test -d 1200000 $file)
26678         echo $offset
26679         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26680
26681         # start beyond file end
26682         printf "Using offset > filesize ... "
26683         lseek_test -l 4000000 $file && error "lseek should fail"
26684         printf "Using offset > filesize ... "
26685         lseek_test -d 4000000 $file && error "lseek should fail"
26686
26687         printf "Done\n\n"
26688 }
26689
26690 test_430a() {
26691         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26692                 skip "MDT does not support SEEK_HOLE"
26693
26694         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26695                 skip "OST does not support SEEK_HOLE"
26696
26697         local file=$DIR/$tdir/$tfile
26698
26699         mkdir -p $DIR/$tdir
26700
26701         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26702         # OST stripe #1 will have continuous data at [1M, 3M)
26703         # OST stripe #2 is empty
26704         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26705         lseek_test_430 $file
26706         rm $file
26707         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26708         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26709         lseek_test_430 $file
26710         rm $file
26711         $LFS setstripe -c2 -S 512K $file
26712         echo "Two stripes, stripe size 512K"
26713         lseek_test_430 $file
26714         rm $file
26715         # FLR with stale mirror
26716         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26717                        -N -c2 -S 1M $file
26718         echo "Mirrored file:"
26719         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26720         echo "Plain 2 stripes 1M"
26721         lseek_test_430 $file
26722         rm $file
26723 }
26724 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26725
26726 test_430b() {
26727         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26728                 skip "OST does not support SEEK_HOLE"
26729
26730         local offset
26731         local file=$DIR/$tdir/$tfile
26732
26733         mkdir -p $DIR/$tdir
26734         # Empty layout lseek should fail
26735         $MCREATE $file
26736         # seek from 0
26737         printf "Seeking hole from 0 ... "
26738         lseek_test -l 0 $file && error "lseek should fail"
26739         printf "Seeking data from 0 ... "
26740         lseek_test -d 0 $file && error "lseek should fail"
26741         rm $file
26742
26743         # 1M-hole file
26744         $LFS setstripe -E 1M -c2 -E eof $file
26745         $TRUNCATE $file 1048576
26746         printf "Seeking hole from 1000000 ... "
26747         offset=$(lseek_test -l 1000000 $file)
26748         echo $offset
26749         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26750         printf "Seeking data from 1000000 ... "
26751         lseek_test -d 1000000 $file && error "lseek should fail"
26752         rm $file
26753
26754         # full component followed by non-inited one
26755         $LFS setstripe -E 1M -c2 -E eof $file
26756         dd if=/dev/urandom of=$file bs=1M count=1
26757         printf "Seeking hole from 1000000 ... "
26758         offset=$(lseek_test -l 1000000 $file)
26759         echo $offset
26760         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26761         printf "Seeking hole from 1048576 ... "
26762         lseek_test -l 1048576 $file && error "lseek should fail"
26763         # init second component and truncate back
26764         echo "123" >> $file
26765         $TRUNCATE $file 1048576
26766         printf "Seeking hole from 1000000 ... "
26767         offset=$(lseek_test -l 1000000 $file)
26768         echo $offset
26769         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26770         printf "Seeking hole from 1048576 ... "
26771         lseek_test -l 1048576 $file && error "lseek should fail"
26772         # boundary checks for big values
26773         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26774         offset=$(lseek_test -d 0 $file.10g)
26775         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26776         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26777         offset=$(lseek_test -d 0 $file.100g)
26778         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26779         return 0
26780 }
26781 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26782
26783 test_430c() {
26784         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26785                 skip "OST does not support SEEK_HOLE"
26786
26787         local file=$DIR/$tdir/$tfile
26788         local start
26789
26790         mkdir -p $DIR/$tdir
26791         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26792
26793         # cp version 8.33+ prefers lseek over fiemap
26794         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26795                 start=$SECONDS
26796                 time cp $file /dev/null
26797                 (( SECONDS - start < 5 )) ||
26798                         error "cp: too long runtime $((SECONDS - start))"
26799
26800         fi
26801         # tar version 1.29+ supports SEEK_HOLE/DATA
26802         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26803                 start=$SECONDS
26804                 time tar cS $file - | cat > /dev/null
26805                 (( SECONDS - start < 5 )) ||
26806                         error "tar: too long runtime $((SECONDS - start))"
26807         fi
26808 }
26809 run_test 430c "lseek: external tools check"
26810
26811 test_431() { # LU-14187
26812         local file=$DIR/$tdir/$tfile
26813
26814         mkdir -p $DIR/$tdir
26815         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26816         dd if=/dev/urandom of=$file bs=4k count=1
26817         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26818         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26819         #define OBD_FAIL_OST_RESTART_IO 0x251
26820         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26821         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26822         cp $file $file.0
26823         cancel_lru_locks
26824         sync_all_data
26825         echo 3 > /proc/sys/vm/drop_caches
26826         diff  $file $file.0 || error "data diff"
26827 }
26828 run_test 431 "Restart transaction for IO"
26829
26830 cleanup_test_432() {
26831         do_facet mgs $LCTL nodemap_activate 0
26832         wait_nm_sync active
26833 }
26834
26835 test_432() {
26836         local tmpdir=$TMP/dir432
26837
26838         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26839                 skip "Need MDS version at least 2.14.52"
26840
26841         stack_trap cleanup_test_432 EXIT
26842         mkdir $DIR/$tdir
26843         mkdir $tmpdir
26844
26845         do_facet mgs $LCTL nodemap_activate 1
26846         wait_nm_sync active
26847         do_facet mgs $LCTL nodemap_modify --name default \
26848                 --property admin --value 1
26849         do_facet mgs $LCTL nodemap_modify --name default \
26850                 --property trusted --value 1
26851         cancel_lru_locks mdc
26852         wait_nm_sync default admin_nodemap
26853         wait_nm_sync default trusted_nodemap
26854
26855         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26856                grep -ci "Operation not permitted") -ne 0 ]; then
26857                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26858         fi
26859 }
26860 run_test 432 "mv dir from outside Lustre"
26861
26862 prep_801() {
26863         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26864         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26865                 skip "Need server version at least 2.9.55"
26866
26867         start_full_debug_logging
26868 }
26869
26870 post_801() {
26871         stop_full_debug_logging
26872 }
26873
26874 barrier_stat() {
26875         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26876                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26877                            awk '/The barrier for/ { print $7 }')
26878                 echo $st
26879         else
26880                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26881                 echo \'$st\'
26882         fi
26883 }
26884
26885 barrier_expired() {
26886         local expired
26887
26888         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26889                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26890                           awk '/will be expired/ { print $7 }')
26891         else
26892                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26893         fi
26894
26895         echo $expired
26896 }
26897
26898 test_801a() {
26899         prep_801
26900
26901         echo "Start barrier_freeze at: $(date)"
26902         #define OBD_FAIL_BARRIER_DELAY          0x2202
26903         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26904         # Do not reduce barrier time - See LU-11873
26905         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26906
26907         sleep 2
26908         local b_status=$(barrier_stat)
26909         echo "Got barrier status at: $(date)"
26910         [ "$b_status" = "'freezing_p1'" ] ||
26911                 error "(1) unexpected barrier status $b_status"
26912
26913         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26914         wait
26915         b_status=$(barrier_stat)
26916         [ "$b_status" = "'frozen'" ] ||
26917                 error "(2) unexpected barrier status $b_status"
26918
26919         local expired=$(barrier_expired)
26920         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26921         sleep $((expired + 3))
26922
26923         b_status=$(barrier_stat)
26924         [ "$b_status" = "'expired'" ] ||
26925                 error "(3) unexpected barrier status $b_status"
26926
26927         # Do not reduce barrier time - See LU-11873
26928         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26929                 error "(4) fail to freeze barrier"
26930
26931         b_status=$(barrier_stat)
26932         [ "$b_status" = "'frozen'" ] ||
26933                 error "(5) unexpected barrier status $b_status"
26934
26935         echo "Start barrier_thaw at: $(date)"
26936         #define OBD_FAIL_BARRIER_DELAY          0x2202
26937         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26938         do_facet mgs $LCTL barrier_thaw $FSNAME &
26939
26940         sleep 2
26941         b_status=$(barrier_stat)
26942         echo "Got barrier status at: $(date)"
26943         [ "$b_status" = "'thawing'" ] ||
26944                 error "(6) unexpected barrier status $b_status"
26945
26946         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26947         wait
26948         b_status=$(barrier_stat)
26949         [ "$b_status" = "'thawed'" ] ||
26950                 error "(7) unexpected barrier status $b_status"
26951
26952         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26953         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26954         do_facet mgs $LCTL barrier_freeze $FSNAME
26955
26956         b_status=$(barrier_stat)
26957         [ "$b_status" = "'failed'" ] ||
26958                 error "(8) unexpected barrier status $b_status"
26959
26960         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26961         do_facet mgs $LCTL barrier_thaw $FSNAME
26962
26963         post_801
26964 }
26965 run_test 801a "write barrier user interfaces and stat machine"
26966
26967 test_801b() {
26968         prep_801
26969
26970         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26971         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26972         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26973         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26974         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26975
26976         cancel_lru_locks mdc
26977
26978         # 180 seconds should be long enough
26979         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26980
26981         local b_status=$(barrier_stat)
26982         [ "$b_status" = "'frozen'" ] ||
26983                 error "(6) unexpected barrier status $b_status"
26984
26985         mkdir $DIR/$tdir/d0/d10 &
26986         mkdir_pid=$!
26987
26988         touch $DIR/$tdir/d1/f13 &
26989         touch_pid=$!
26990
26991         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26992         ln_pid=$!
26993
26994         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26995         mv_pid=$!
26996
26997         rm -f $DIR/$tdir/d4/f12 &
26998         rm_pid=$!
26999
27000         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27001
27002         # To guarantee taht the 'stat' is not blocked
27003         b_status=$(barrier_stat)
27004         [ "$b_status" = "'frozen'" ] ||
27005                 error "(8) unexpected barrier status $b_status"
27006
27007         # let above commands to run at background
27008         sleep 5
27009
27010         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27011         ps -p $touch_pid || error "(10) touch should be blocked"
27012         ps -p $ln_pid || error "(11) link should be blocked"
27013         ps -p $mv_pid || error "(12) rename should be blocked"
27014         ps -p $rm_pid || error "(13) unlink should be blocked"
27015
27016         b_status=$(barrier_stat)
27017         [ "$b_status" = "'frozen'" ] ||
27018                 error "(14) unexpected barrier status $b_status"
27019
27020         do_facet mgs $LCTL barrier_thaw $FSNAME
27021         b_status=$(barrier_stat)
27022         [ "$b_status" = "'thawed'" ] ||
27023                 error "(15) unexpected barrier status $b_status"
27024
27025         wait $mkdir_pid || error "(16) mkdir should succeed"
27026         wait $touch_pid || error "(17) touch should succeed"
27027         wait $ln_pid || error "(18) link should succeed"
27028         wait $mv_pid || error "(19) rename should succeed"
27029         wait $rm_pid || error "(20) unlink should succeed"
27030
27031         post_801
27032 }
27033 run_test 801b "modification will be blocked by write barrier"
27034
27035 test_801c() {
27036         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27037
27038         prep_801
27039
27040         stop mds2 || error "(1) Fail to stop mds2"
27041
27042         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27043
27044         local b_status=$(barrier_stat)
27045         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27046                 do_facet mgs $LCTL barrier_thaw $FSNAME
27047                 error "(2) unexpected barrier status $b_status"
27048         }
27049
27050         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27051                 error "(3) Fail to rescan barrier bitmap"
27052
27053         # Do not reduce barrier time - See LU-11873
27054         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27055
27056         b_status=$(barrier_stat)
27057         [ "$b_status" = "'frozen'" ] ||
27058                 error "(4) unexpected barrier status $b_status"
27059
27060         do_facet mgs $LCTL barrier_thaw $FSNAME
27061         b_status=$(barrier_stat)
27062         [ "$b_status" = "'thawed'" ] ||
27063                 error "(5) unexpected barrier status $b_status"
27064
27065         local devname=$(mdsdevname 2)
27066
27067         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27068
27069         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27070                 error "(7) Fail to rescan barrier bitmap"
27071
27072         post_801
27073 }
27074 run_test 801c "rescan barrier bitmap"
27075
27076 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
27077 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
27078 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
27079 saved_MOUNT_OPTS=$MOUNT_OPTS
27080
27081 cleanup_802a() {
27082         trap 0
27083
27084         stopall
27085         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
27086         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
27087         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
27088         MOUNT_OPTS=$saved_MOUNT_OPTS
27089         setupall
27090 }
27091
27092 test_802a() {
27093         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
27094         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27095         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27096                 skip "Need server version at least 2.9.55"
27097
27098         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
27099
27100         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27101
27102         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27103                 error "(2) Fail to copy"
27104
27105         trap cleanup_802a EXIT
27106
27107         # sync by force before remount as readonly
27108         sync; sync_all_data; sleep 3; sync_all_data
27109
27110         stopall
27111
27112         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
27113         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
27114         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
27115
27116         echo "Mount the server as read only"
27117         setupall server_only || error "(3) Fail to start servers"
27118
27119         echo "Mount client without ro should fail"
27120         mount_client $MOUNT &&
27121                 error "(4) Mount client without 'ro' should fail"
27122
27123         echo "Mount client with ro should succeed"
27124         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
27125         mount_client $MOUNT ||
27126                 error "(5) Mount client with 'ro' should succeed"
27127
27128         echo "Modify should be refused"
27129         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27130
27131         echo "Read should be allowed"
27132         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27133                 error "(7) Read should succeed under ro mode"
27134
27135         cleanup_802a
27136 }
27137 run_test 802a "simulate readonly device"
27138
27139 test_802b() {
27140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27141         remote_mds_nodsh && skip "remote MDS with nodsh"
27142
27143         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27144                 skip "readonly option not available"
27145
27146         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27147
27148         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27149                 error "(2) Fail to copy"
27150
27151         # write back all cached data before setting MDT to readonly
27152         cancel_lru_locks
27153         sync_all_data
27154
27155         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27156         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27157
27158         echo "Modify should be refused"
27159         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27160
27161         echo "Read should be allowed"
27162         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27163                 error "(7) Read should succeed under ro mode"
27164
27165         # disable readonly
27166         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27167 }
27168 run_test 802b "be able to set MDTs to readonly"
27169
27170 test_803a() {
27171         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27172         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27173                 skip "MDS needs to be newer than 2.10.54"
27174
27175         mkdir_on_mdt0 $DIR/$tdir
27176         # Create some objects on all MDTs to trigger related logs objects
27177         for idx in $(seq $MDSCOUNT); do
27178                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27179                         $DIR/$tdir/dir${idx} ||
27180                         error "Fail to create $DIR/$tdir/dir${idx}"
27181         done
27182
27183         sync; sleep 3
27184         wait_delete_completed # ensure old test cleanups are finished
27185         echo "before create:"
27186         $LFS df -i $MOUNT
27187         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27188
27189         for i in {1..10}; do
27190                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27191                         error "Fail to create $DIR/$tdir/foo$i"
27192         done
27193
27194         sync; sleep 3
27195         echo "after create:"
27196         $LFS df -i $MOUNT
27197         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27198
27199         # allow for an llog to be cleaned up during the test
27200         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27201                 error "before ($before_used) + 10 > after ($after_used)"
27202
27203         for i in {1..10}; do
27204                 rm -rf $DIR/$tdir/foo$i ||
27205                         error "Fail to remove $DIR/$tdir/foo$i"
27206         done
27207
27208         sleep 3 # avoid MDT return cached statfs
27209         wait_delete_completed
27210         echo "after unlink:"
27211         $LFS df -i $MOUNT
27212         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27213
27214         # allow for an llog to be created during the test
27215         [ $after_used -le $((before_used + 1)) ] ||
27216                 error "after ($after_used) > before ($before_used) + 1"
27217 }
27218 run_test 803a "verify agent object for remote object"
27219
27220 test_803b() {
27221         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27222         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27223                 skip "MDS needs to be newer than 2.13.56"
27224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27225
27226         for i in $(seq 0 $((MDSCOUNT - 1))); do
27227                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27228         done
27229
27230         local before=0
27231         local after=0
27232
27233         local tmp
27234
27235         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27236         for i in $(seq 0 $((MDSCOUNT - 1))); do
27237                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27238                         awk '/getattr/ { print $2 }')
27239                 before=$((before + tmp))
27240         done
27241         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
27242         for i in $(seq 0 $((MDSCOUNT - 1))); do
27243                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
27244                         awk '/getattr/ { print $2 }')
27245                 after=$((after + tmp))
27246         done
27247
27248         [ $before -eq $after ] || error "getattr count $before != $after"
27249 }
27250 run_test 803b "remote object can getattr from cache"
27251
27252 test_804() {
27253         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27254         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27255                 skip "MDS needs to be newer than 2.10.54"
27256         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
27257
27258         mkdir -p $DIR/$tdir
27259         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
27260                 error "Fail to create $DIR/$tdir/dir0"
27261
27262         local fid=$($LFS path2fid $DIR/$tdir/dir0)
27263         local dev=$(mdsdevname 2)
27264
27265         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27266                 grep ${fid} || error "NOT found agent entry for dir0"
27267
27268         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
27269                 error "Fail to create $DIR/$tdir/dir1"
27270
27271         touch $DIR/$tdir/dir1/foo0 ||
27272                 error "Fail to create $DIR/$tdir/dir1/foo0"
27273         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
27274         local rc=0
27275
27276         for idx in $(seq $MDSCOUNT); do
27277                 dev=$(mdsdevname $idx)
27278                 do_facet mds${idx} \
27279                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27280                         grep ${fid} && rc=$idx
27281         done
27282
27283         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27284                 error "Fail to rename foo0 to foo1"
27285         if [ $rc -eq 0 ]; then
27286                 for idx in $(seq $MDSCOUNT); do
27287                         dev=$(mdsdevname $idx)
27288                         do_facet mds${idx} \
27289                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27290                         grep ${fid} && rc=$idx
27291                 done
27292         fi
27293
27294         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27295                 error "Fail to rename foo1 to foo2"
27296         if [ $rc -eq 0 ]; then
27297                 for idx in $(seq $MDSCOUNT); do
27298                         dev=$(mdsdevname $idx)
27299                         do_facet mds${idx} \
27300                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27301                         grep ${fid} && rc=$idx
27302                 done
27303         fi
27304
27305         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27306
27307         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27308                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27309         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27310                 error "Fail to rename foo2 to foo0"
27311         unlink $DIR/$tdir/dir1/foo0 ||
27312                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27313         rm -rf $DIR/$tdir/dir0 ||
27314                 error "Fail to rm $DIR/$tdir/dir0"
27315
27316         for idx in $(seq $MDSCOUNT); do
27317                 rc=0
27318
27319                 stop mds${idx}
27320                 dev=$(mdsdevname $idx)
27321                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27322                         rc=$?
27323                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27324                         error "mount mds$idx failed"
27325                 df $MOUNT > /dev/null 2>&1
27326
27327                 # e2fsck should not return error
27328                 [ $rc -eq 0 ] ||
27329                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27330         done
27331 }
27332 run_test 804 "verify agent entry for remote entry"
27333
27334 cleanup_805() {
27335         do_facet $SINGLEMDS zfs set quota=$old $fsset
27336         unlinkmany $DIR/$tdir/f- 1000000
27337         trap 0
27338 }
27339
27340 test_805() {
27341         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27342         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27343         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27344                 skip "netfree not implemented before 0.7"
27345         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27346                 skip "Need MDS version at least 2.10.57"
27347
27348         local fsset
27349         local freekb
27350         local usedkb
27351         local old
27352         local quota
27353         local pref="osd-zfs.$FSNAME-MDT0000."
27354
27355         # limit available space on MDS dataset to meet nospace issue
27356         # quickly. then ZFS 0.7.2 can use reserved space if asked
27357         # properly (using netfree flag in osd_declare_destroy()
27358         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27359         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27360                 gawk '{print $3}')
27361         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27362         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27363         let "usedkb=usedkb-freekb"
27364         let "freekb=freekb/2"
27365         if let "freekb > 5000"; then
27366                 let "freekb=5000"
27367         fi
27368         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27369         trap cleanup_805 EXIT
27370         mkdir_on_mdt0 $DIR/$tdir
27371         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27372                 error "Can't set PFL layout"
27373         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27374         rm -rf $DIR/$tdir || error "not able to remove"
27375         do_facet $SINGLEMDS zfs set quota=$old $fsset
27376         trap 0
27377 }
27378 run_test 805 "ZFS can remove from full fs"
27379
27380 # Size-on-MDS test
27381 check_lsom_data()
27382 {
27383         local file=$1
27384         local expect=$(stat -c %s $file)
27385
27386         check_lsom_size $1 $expect
27387
27388         local blocks=$($LFS getsom -b $file)
27389         expect=$(stat -c %b $file)
27390         [[ $blocks == $expect ]] ||
27391                 error "$file expected blocks: $expect, got: $blocks"
27392 }
27393
27394 check_lsom_size()
27395 {
27396         local size
27397         local expect=$2
27398
27399         cancel_lru_locks mdc
27400
27401         size=$($LFS getsom -s $1)
27402         [[ $size == $expect ]] ||
27403                 error "$file expected size: $expect, got: $size"
27404 }
27405
27406 test_806() {
27407         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27408                 skip "Need MDS version at least 2.11.52"
27409
27410         local bs=1048576
27411
27412         touch $DIR/$tfile || error "touch $tfile failed"
27413
27414         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27415         save_lustre_params client "llite.*.xattr_cache" > $save
27416         lctl set_param llite.*.xattr_cache=0
27417         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27418
27419         # single-threaded write
27420         echo "Test SOM for single-threaded write"
27421         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27422                 error "write $tfile failed"
27423         check_lsom_size $DIR/$tfile $bs
27424
27425         local num=32
27426         local size=$(($num * $bs))
27427         local offset=0
27428         local i
27429
27430         echo "Test SOM for single client multi-threaded($num) write"
27431         $TRUNCATE $DIR/$tfile 0
27432         for ((i = 0; i < $num; i++)); do
27433                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27434                 local pids[$i]=$!
27435                 offset=$((offset + $bs))
27436         done
27437         for (( i=0; i < $num; i++ )); do
27438                 wait ${pids[$i]}
27439         done
27440         check_lsom_size $DIR/$tfile $size
27441
27442         $TRUNCATE $DIR/$tfile 0
27443         for ((i = 0; i < $num; i++)); do
27444                 offset=$((offset - $bs))
27445                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27446                 local pids[$i]=$!
27447         done
27448         for (( i=0; i < $num; i++ )); do
27449                 wait ${pids[$i]}
27450         done
27451         check_lsom_size $DIR/$tfile $size
27452
27453         # multi-client writes
27454         num=$(get_node_count ${CLIENTS//,/ })
27455         size=$(($num * $bs))
27456         offset=0
27457         i=0
27458
27459         echo "Test SOM for multi-client ($num) writes"
27460         $TRUNCATE $DIR/$tfile 0
27461         for client in ${CLIENTS//,/ }; do
27462                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27463                 local pids[$i]=$!
27464                 i=$((i + 1))
27465                 offset=$((offset + $bs))
27466         done
27467         for (( i=0; i < $num; i++ )); do
27468                 wait ${pids[$i]}
27469         done
27470         check_lsom_size $DIR/$tfile $offset
27471
27472         i=0
27473         $TRUNCATE $DIR/$tfile 0
27474         for client in ${CLIENTS//,/ }; do
27475                 offset=$((offset - $bs))
27476                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27477                 local pids[$i]=$!
27478                 i=$((i + 1))
27479         done
27480         for (( i=0; i < $num; i++ )); do
27481                 wait ${pids[$i]}
27482         done
27483         check_lsom_size $DIR/$tfile $size
27484
27485         # verify truncate
27486         echo "Test SOM for truncate"
27487         $TRUNCATE $DIR/$tfile 1048576
27488         check_lsom_size $DIR/$tfile 1048576
27489         $TRUNCATE $DIR/$tfile 1234
27490         check_lsom_size $DIR/$tfile 1234
27491
27492         # verify SOM blocks count
27493         echo "Verify SOM block count"
27494         $TRUNCATE $DIR/$tfile 0
27495         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27496                 error "failed to write file $tfile"
27497         check_lsom_data $DIR/$tfile
27498 }
27499 run_test 806 "Verify Lazy Size on MDS"
27500
27501 test_807() {
27502         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27503         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27504                 skip "Need MDS version at least 2.11.52"
27505
27506         # Registration step
27507         changelog_register || error "changelog_register failed"
27508         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27509         changelog_users $SINGLEMDS | grep -q $cl_user ||
27510                 error "User $cl_user not found in changelog_users"
27511
27512         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27513         save_lustre_params client "llite.*.xattr_cache" > $save
27514         lctl set_param llite.*.xattr_cache=0
27515         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27516
27517         rm -rf $DIR/$tdir || error "rm $tdir failed"
27518         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27519         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27520         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27521         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27522                 error "truncate $tdir/trunc failed"
27523
27524         local bs=1048576
27525         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27526                 error "write $tfile failed"
27527
27528         # multi-client wirtes
27529         local num=$(get_node_count ${CLIENTS//,/ })
27530         local offset=0
27531         local i=0
27532
27533         echo "Test SOM for multi-client ($num) writes"
27534         touch $DIR/$tfile || error "touch $tfile failed"
27535         $TRUNCATE $DIR/$tfile 0
27536         for client in ${CLIENTS//,/ }; do
27537                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27538                 local pids[$i]=$!
27539                 i=$((i + 1))
27540                 offset=$((offset + $bs))
27541         done
27542         for (( i=0; i < $num; i++ )); do
27543                 wait ${pids[$i]}
27544         done
27545
27546         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27547         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27548         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27549         check_lsom_data $DIR/$tdir/trunc
27550         check_lsom_data $DIR/$tdir/single_dd
27551         check_lsom_data $DIR/$tfile
27552
27553         rm -rf $DIR/$tdir
27554         # Deregistration step
27555         changelog_deregister || error "changelog_deregister failed"
27556 }
27557 run_test 807 "verify LSOM syncing tool"
27558
27559 check_som_nologged()
27560 {
27561         local lines=$($LFS changelog $FSNAME-MDT0000 |
27562                 grep 'x=trusted.som' | wc -l)
27563         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27564 }
27565
27566 test_808() {
27567         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27568                 skip "Need MDS version at least 2.11.55"
27569
27570         # Registration step
27571         changelog_register || error "changelog_register failed"
27572
27573         touch $DIR/$tfile || error "touch $tfile failed"
27574         check_som_nologged
27575
27576         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27577                 error "write $tfile failed"
27578         check_som_nologged
27579
27580         $TRUNCATE $DIR/$tfile 1234
27581         check_som_nologged
27582
27583         $TRUNCATE $DIR/$tfile 1048576
27584         check_som_nologged
27585
27586         # Deregistration step
27587         changelog_deregister || error "changelog_deregister failed"
27588 }
27589 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27590
27591 check_som_nodata()
27592 {
27593         $LFS getsom $1
27594         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27595 }
27596
27597 test_809() {
27598         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27599                 skip "Need MDS version at least 2.11.56"
27600
27601         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27602                 error "failed to create DoM-only file $DIR/$tfile"
27603         touch $DIR/$tfile || error "touch $tfile failed"
27604         check_som_nodata $DIR/$tfile
27605
27606         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27607                 error "write $tfile failed"
27608         check_som_nodata $DIR/$tfile
27609
27610         $TRUNCATE $DIR/$tfile 1234
27611         check_som_nodata $DIR/$tfile
27612
27613         $TRUNCATE $DIR/$tfile 4097
27614         check_som_nodata $DIR/$file
27615 }
27616 run_test 809 "Verify no SOM xattr store for DoM-only files"
27617
27618 test_810() {
27619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27620         $GSS && skip_env "could not run with gss"
27621         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27622                 skip "OST < 2.12.58 doesn't align checksum"
27623
27624         set_checksums 1
27625         stack_trap "set_checksums $ORIG_CSUM" EXIT
27626         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27627
27628         local csum
27629         local before
27630         local after
27631         for csum in $CKSUM_TYPES; do
27632                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27633                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27634                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27635                         eval set -- $i
27636                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27637                         before=$(md5sum $DIR/$tfile)
27638                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27639                         after=$(md5sum $DIR/$tfile)
27640                         [ "$before" == "$after" ] ||
27641                                 error "$csum: $before != $after bs=$1 seek=$2"
27642                 done
27643         done
27644 }
27645 run_test 810 "partial page writes on ZFS (LU-11663)"
27646
27647 test_812a() {
27648         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27649                 skip "OST < 2.12.51 doesn't support this fail_loc"
27650
27651         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27652         # ensure ost1 is connected
27653         stat $DIR/$tfile >/dev/null || error "can't stat"
27654         wait_osc_import_state client ost1 FULL
27655         # no locks, no reqs to let the connection idle
27656         cancel_lru_locks osc
27657
27658         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27659 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27660         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27661         wait_osc_import_state client ost1 CONNECTING
27662         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27663
27664         stat $DIR/$tfile >/dev/null || error "can't stat file"
27665 }
27666 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27667
27668 test_812b() { # LU-12378
27669         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27670                 skip "OST < 2.12.51 doesn't support this fail_loc"
27671
27672         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27673         # ensure ost1 is connected
27674         stat $DIR/$tfile >/dev/null || error "can't stat"
27675         wait_osc_import_state client ost1 FULL
27676         # no locks, no reqs to let the connection idle
27677         cancel_lru_locks osc
27678
27679         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27680 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27681         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27682         wait_osc_import_state client ost1 CONNECTING
27683         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27684
27685         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27686         wait_osc_import_state client ost1 IDLE
27687 }
27688 run_test 812b "do not drop no resend request for idle connect"
27689
27690 test_812c() {
27691         local old
27692
27693         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27694
27695         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27696         $LFS getstripe $DIR/$tfile
27697         $LCTL set_param osc.*.idle_timeout=10
27698         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27699         # ensure ost1 is connected
27700         stat $DIR/$tfile >/dev/null || error "can't stat"
27701         wait_osc_import_state client ost1 FULL
27702         # no locks, no reqs to let the connection idle
27703         cancel_lru_locks osc
27704
27705 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27706         $LCTL set_param fail_loc=0x80000533
27707         sleep 15
27708         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27709 }
27710 run_test 812c "idle import vs lock enqueue race"
27711
27712 test_813() {
27713         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27714         [ -z "$file_heat_sav" ] && skip "no file heat support"
27715
27716         local readsample
27717         local writesample
27718         local readbyte
27719         local writebyte
27720         local readsample1
27721         local writesample1
27722         local readbyte1
27723         local writebyte1
27724
27725         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27726         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27727
27728         $LCTL set_param -n llite.*.file_heat=1
27729         echo "Turn on file heat"
27730         echo "Period second: $period_second, Decay percentage: $decay_pct"
27731
27732         echo "QQQQ" > $DIR/$tfile
27733         echo "QQQQ" > $DIR/$tfile
27734         echo "QQQQ" > $DIR/$tfile
27735         cat $DIR/$tfile > /dev/null
27736         cat $DIR/$tfile > /dev/null
27737         cat $DIR/$tfile > /dev/null
27738         cat $DIR/$tfile > /dev/null
27739
27740         local out=$($LFS heat_get $DIR/$tfile)
27741
27742         $LFS heat_get $DIR/$tfile
27743         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27744         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27745         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27746         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27747
27748         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27749         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27750         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27751         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27752
27753         sleep $((period_second + 3))
27754         echo "Sleep $((period_second + 3)) seconds..."
27755         # The recursion formula to calculate the heat of the file f is as
27756         # follow:
27757         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27758         # Where Hi is the heat value in the period between time points i*I and
27759         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27760         # to the weight of Ci.
27761         out=$($LFS heat_get $DIR/$tfile)
27762         $LFS heat_get $DIR/$tfile
27763         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27764         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27765         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27766         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27767
27768         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27769                 error "read sample ($readsample) is wrong"
27770         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27771                 error "write sample ($writesample) is wrong"
27772         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27773                 error "read bytes ($readbyte) is wrong"
27774         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27775                 error "write bytes ($writebyte) is wrong"
27776
27777         echo "QQQQ" > $DIR/$tfile
27778         echo "QQQQ" > $DIR/$tfile
27779         echo "QQQQ" > $DIR/$tfile
27780         cat $DIR/$tfile > /dev/null
27781         cat $DIR/$tfile > /dev/null
27782         cat $DIR/$tfile > /dev/null
27783         cat $DIR/$tfile > /dev/null
27784
27785         sleep $((period_second + 3))
27786         echo "Sleep $((period_second + 3)) seconds..."
27787
27788         out=$($LFS heat_get $DIR/$tfile)
27789         $LFS heat_get $DIR/$tfile
27790         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27791         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27792         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27793         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27794
27795         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27796                 4 * $decay_pct) / 100") -eq 1 ] ||
27797                 error "read sample ($readsample1) is wrong"
27798         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27799                 3 * $decay_pct) / 100") -eq 1 ] ||
27800                 error "write sample ($writesample1) is wrong"
27801         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27802                 20 * $decay_pct) / 100") -eq 1 ] ||
27803                 error "read bytes ($readbyte1) is wrong"
27804         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27805                 15 * $decay_pct) / 100") -eq 1 ] ||
27806                 error "write bytes ($writebyte1) is wrong"
27807
27808         echo "Turn off file heat for the file $DIR/$tfile"
27809         $LFS heat_set -o $DIR/$tfile
27810
27811         echo "QQQQ" > $DIR/$tfile
27812         echo "QQQQ" > $DIR/$tfile
27813         echo "QQQQ" > $DIR/$tfile
27814         cat $DIR/$tfile > /dev/null
27815         cat $DIR/$tfile > /dev/null
27816         cat $DIR/$tfile > /dev/null
27817         cat $DIR/$tfile > /dev/null
27818
27819         out=$($LFS heat_get $DIR/$tfile)
27820         $LFS heat_get $DIR/$tfile
27821         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27822         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27823         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27824         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27825
27826         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27827         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27828         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27829         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27830
27831         echo "Trun on file heat for the file $DIR/$tfile"
27832         $LFS heat_set -O $DIR/$tfile
27833
27834         echo "QQQQ" > $DIR/$tfile
27835         echo "QQQQ" > $DIR/$tfile
27836         echo "QQQQ" > $DIR/$tfile
27837         cat $DIR/$tfile > /dev/null
27838         cat $DIR/$tfile > /dev/null
27839         cat $DIR/$tfile > /dev/null
27840         cat $DIR/$tfile > /dev/null
27841
27842         out=$($LFS heat_get $DIR/$tfile)
27843         $LFS heat_get $DIR/$tfile
27844         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27845         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27846         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27847         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27848
27849         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27850         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27851         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27852         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27853
27854         $LFS heat_set -c $DIR/$tfile
27855         $LCTL set_param -n llite.*.file_heat=0
27856         echo "Turn off file heat support for the Lustre filesystem"
27857
27858         echo "QQQQ" > $DIR/$tfile
27859         echo "QQQQ" > $DIR/$tfile
27860         echo "QQQQ" > $DIR/$tfile
27861         cat $DIR/$tfile > /dev/null
27862         cat $DIR/$tfile > /dev/null
27863         cat $DIR/$tfile > /dev/null
27864         cat $DIR/$tfile > /dev/null
27865
27866         out=$($LFS heat_get $DIR/$tfile)
27867         $LFS heat_get $DIR/$tfile
27868         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27869         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27870         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27871         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27872
27873         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27874         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27875         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27876         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27877
27878         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27879         rm -f $DIR/$tfile
27880 }
27881 run_test 813 "File heat verfication"
27882
27883 test_814()
27884 {
27885         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27886         echo -n y >> $DIR/$tfile
27887         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27888         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27889 }
27890 run_test 814 "sparse cp works as expected (LU-12361)"
27891
27892 test_815()
27893 {
27894         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27895         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27896 }
27897 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27898
27899 test_816() {
27900         local ost1_imp=$(get_osc_import_name client ost1)
27901         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27902                          cut -d'.' -f2)
27903
27904         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27905         # ensure ost1 is connected
27906
27907         stat $DIR/$tfile >/dev/null || error "can't stat"
27908         wait_osc_import_state client ost1 FULL
27909         # no locks, no reqs to let the connection idle
27910         cancel_lru_locks osc
27911         lru_resize_disable osc
27912         local before
27913         local now
27914         before=$($LCTL get_param -n \
27915                  ldlm.namespaces.$imp_name.lru_size)
27916
27917         wait_osc_import_state client ost1 IDLE
27918         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27919         now=$($LCTL get_param -n \
27920               ldlm.namespaces.$imp_name.lru_size)
27921         [ $before == $now ] || error "lru_size changed $before != $now"
27922 }
27923 run_test 816 "do not reset lru_resize on idle reconnect"
27924
27925 cleanup_817() {
27926         umount $tmpdir
27927         exportfs -u localhost:$DIR/nfsexp
27928         rm -rf $DIR/nfsexp
27929 }
27930
27931 test_817() {
27932         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27933
27934         mkdir -p $DIR/nfsexp
27935         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27936                 error "failed to export nfs"
27937
27938         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27939         stack_trap cleanup_817 EXIT
27940
27941         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27942                 error "failed to mount nfs to $tmpdir"
27943
27944         cp /bin/true $tmpdir
27945         $DIR/nfsexp/true || error "failed to execute 'true' command"
27946 }
27947 run_test 817 "nfsd won't cache write lock for exec file"
27948
27949 test_818() {
27950         test_mkdir -i0 -c1 $DIR/$tdir
27951         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27952         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27953         stop $SINGLEMDS
27954
27955         # restore osp-syn threads
27956         stack_trap "fail $SINGLEMDS"
27957
27958         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27959         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27960         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27961                 error "start $SINGLEMDS failed"
27962         rm -rf $DIR/$tdir
27963
27964         local testid=$(echo $TESTNAME | tr '_' ' ')
27965
27966         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27967                 grep "run LFSCK" || error "run LFSCK is not suggested"
27968 }
27969 run_test 818 "unlink with failed llog"
27970
27971 test_819a() {
27972         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27973         cancel_lru_locks osc
27974         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27975         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27976         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27977         rm -f $TDIR/$tfile
27978 }
27979 run_test 819a "too big niobuf in read"
27980
27981 test_819b() {
27982         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27983         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27984         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27985         cancel_lru_locks osc
27986         sleep 1
27987         rm -f $TDIR/$tfile
27988 }
27989 run_test 819b "too big niobuf in write"
27990
27991
27992 function test_820_start_ost() {
27993         sleep 5
27994
27995         for num in $(seq $OSTCOUNT); do
27996                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27997         done
27998 }
27999
28000 test_820() {
28001         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28002
28003         mkdir $DIR/$tdir
28004         umount_client $MOUNT || error "umount failed"
28005         for num in $(seq $OSTCOUNT); do
28006                 stop ost$num
28007         done
28008
28009         # mount client with no active OSTs
28010         # so that the client can't initialize max LOV EA size
28011         # from OSC notifications
28012         mount_client $MOUNT || error "mount failed"
28013         # delay OST starting to keep this 0 max EA size for a while
28014         test_820_start_ost &
28015
28016         # create a directory on MDS2
28017         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28018                 error "Failed to create directory"
28019         # open intent should update default EA size
28020         # see mdc_update_max_ea_from_body()
28021         # notice this is the very first RPC to MDS2
28022         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28023         ret=$?
28024         echo $out
28025         # With SSK, this situation can lead to -EPERM being returned.
28026         # In that case, simply retry.
28027         if [ $ret -ne 0 ] && $SHARED_KEY; then
28028                 if echo "$out" | grep -q "not permitted"; then
28029                         cp /etc/services $DIR/$tdir/mds2
28030                         ret=$?
28031                 fi
28032         fi
28033         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28034 }
28035 run_test 820 "update max EA from open intent"
28036
28037 test_822() {
28038         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28039
28040         save_lustre_params mds1 \
28041                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28042         do_facet $SINGLEMDS "$LCTL set_param -n \
28043                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
28044         do_facet $SINGLEMDS "$LCTL set_param -n \
28045                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
28046
28047         # wait for statfs update to clear OS_STATFS_NOPRECREATE
28048         local maxage=$(do_facet mds1 $LCTL get_param -n \
28049                        osp.$FSNAME-OST0000*MDT0000.maxage)
28050         sleep $((maxage + 1))
28051
28052         #define OBD_FAIL_NET_ERROR_RPC          0x532
28053         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
28054
28055         stack_trap "restore_lustre_params < $p; rm $p"
28056
28057         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
28058                       osp.$FSNAME-OST0000*MDT0000.create_count")
28059         for i in $(seq 1 $count); do
28060                 touch $DIR/$tfile.${i} || error "touch failed"
28061         done
28062 }
28063 run_test 822 "test precreate failure"
28064
28065 test_823() {
28066         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28067         local OST_MAX_PRECREATE=20000
28068
28069         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28070                 skip "Need MDS version at least 2.14.56"
28071
28072         save_lustre_params mds1 \
28073                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28074         do_facet $SINGLEMDS "$LCTL set_param -n \
28075                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28076         do_facet $SINGLEMDS "$LCTL set_param -n \
28077                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28078
28079         stack_trap "restore_lustre_params < $p; rm $p"
28080
28081         do_facet $SINGLEMDS "$LCTL set_param -n \
28082                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28083
28084         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28085                       osp.$FSNAME-OST0000*MDT0000.create_count")
28086         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28087                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28088         local expect_count=$(((($max/2)/256) * 256))
28089
28090         log "setting create_count to 100200:"
28091         log " -result- count: $count with max: $max, expecting: $expect_count"
28092
28093         [[ $count -eq expect_count ]] ||
28094                 error "Create count not set to max precreate."
28095 }
28096 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28097
28098 test_831() {
28099         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28100                 skip "Need MDS version 2.14.56"
28101
28102         local sync_changes=$(do_facet $SINGLEMDS \
28103                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28104
28105         [ "$sync_changes" -gt 100 ] &&
28106                 skip "Sync changes $sync_changes > 100 already"
28107
28108         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28109
28110         $LFS mkdir -i 0 $DIR/$tdir
28111         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28112
28113         save_lustre_params mds1 \
28114                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28115         save_lustre_params mds1 \
28116                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28117
28118         do_facet mds1 "$LCTL set_param -n \
28119                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28120                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28121         stack_trap "restore_lustre_params < $p" EXIT
28122
28123         createmany -o $DIR/$tdir/f- 1000
28124         unlinkmany $DIR/$tdir/f- 1000 &
28125         local UNLINK_PID=$!
28126
28127         while sleep 1; do
28128                 sync_changes=$(do_facet mds1 \
28129                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28130                 # the check in the code is racy, fail the test
28131                 # if the value above the limit by 10.
28132                 [ $sync_changes -gt 110 ] && {
28133                         kill -2 $UNLINK_PID
28134                         wait
28135                         error "osp changes throttling failed, $sync_changes>110"
28136                 }
28137                 kill -0 $UNLINK_PID 2> /dev/null || break
28138         done
28139         wait
28140 }
28141 run_test 831 "throttling unlink/setattr queuing on OSP"
28142
28143 #
28144 # tests that do cleanup/setup should be run at the end
28145 #
28146
28147 test_900() {
28148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28149         local ls
28150
28151         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28152         $LCTL set_param fail_loc=0x903
28153
28154         cancel_lru_locks MGC
28155
28156         FAIL_ON_ERROR=true cleanup
28157         FAIL_ON_ERROR=true setup
28158 }
28159 run_test 900 "umount should not race with any mgc requeue thread"
28160
28161 # LUS-6253/LU-11185
28162 test_901() {
28163         local old
28164         local count
28165         local oldc
28166         local newc
28167         local olds
28168         local news
28169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28170
28171         # some get_param have a bug to handle dot in param name
28172         cancel_lru_locks MGC
28173         old=$(mount -t lustre | wc -l)
28174         # 1 config+sptlrpc
28175         # 2 params
28176         # 3 nodemap
28177         # 4 IR
28178         old=$((old * 4))
28179         oldc=0
28180         count=0
28181         while [ $old -ne $oldc ]; do
28182                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28183                 sleep 1
28184                 ((count++))
28185                 if [ $count -ge $TIMEOUT ]; then
28186                         error "too large timeout"
28187                 fi
28188         done
28189         umount_client $MOUNT || error "umount failed"
28190         mount_client $MOUNT || error "mount failed"
28191         cancel_lru_locks MGC
28192         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28193
28194         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28195
28196         return 0
28197 }
28198 run_test 901 "don't leak a mgc lock on client umount"
28199
28200 # LU-13377
28201 test_902() {
28202         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28203                 skip "client does not have LU-13377 fix"
28204         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28205         $LCTL set_param fail_loc=0x1415
28206         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28207         cancel_lru_locks osc
28208         rm -f $DIR/$tfile
28209 }
28210 run_test 902 "test short write doesn't hang lustre"
28211
28212 # LU-14711
28213 test_903() {
28214         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28215         echo "blah" > $DIR/${tfile}-2
28216         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28217         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28218         $LCTL set_param fail_loc=0x417 fail_val=20
28219
28220         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28221         sleep 1 # To start the destroy
28222         wait_destroy_complete 150 || error "Destroy taking too long"
28223         cat $DIR/$tfile > /dev/null || error "Evicted"
28224 }
28225 run_test 903 "Test long page discard does not cause evictions"
28226
28227 test_904() {
28228         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28229         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28230                 grep -q project || skip "skip project quota not supported"
28231
28232         local testfile="$DIR/$tdir/$tfile"
28233         local xattr="trusted.projid"
28234         local projid
28235         local mdts=$(comma_list $(mdts_nodes))
28236         local saved=$(do_facet mds1 $LCTL get_param -n \
28237                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28238
28239         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28240         stack_trap "do_nodes $mdts $LCTL set_param \
28241                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28242
28243         mkdir -p $DIR/$tdir
28244         touch $testfile
28245         #hide projid xattr on server
28246         $LFS project -p 1 $testfile ||
28247                 error "set $testfile project id failed"
28248         getfattr -m - $testfile | grep $xattr &&
28249                 error "do not show trusted.projid when disabled on server"
28250         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
28251         #should be hidden when projid is 0
28252         $LFS project -p 0 $testfile ||
28253                 error "set $testfile project id failed"
28254         getfattr -m - $testfile | grep $xattr &&
28255                 error "do not show trusted.projid with project ID 0"
28256
28257         #still can getxattr explicitly
28258         projid=$(getfattr -n $xattr $testfile |
28259                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28260         [ $projid == "0" ] ||
28261                 error "projid expected 0 not $projid"
28262
28263         #set the projid via setxattr
28264         setfattr -n $xattr -v "1000" $testfile ||
28265                 error "setattr failed with $?"
28266         projid=($($LFS project $testfile))
28267         [ ${projid[0]} == "1000" ] ||
28268                 error "projid expected 1000 not $projid"
28269
28270         #check the new projid via getxattr
28271         $LFS project -p 1001 $testfile ||
28272                 error "set $testfile project id failed"
28273         getfattr -m - $testfile | grep $xattr ||
28274                 error "should show trusted.projid when project ID != 0"
28275         projid=$(getfattr -n $xattr $testfile |
28276                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28277         [ $projid == "1001" ] ||
28278                 error "projid expected 1001 not $projid"
28279
28280         #try to set invalid projid
28281         setfattr -n $xattr -v "4294967295" $testfile &&
28282                 error "set invalid projid should fail"
28283
28284         #remove the xattr means setting projid to 0
28285         setfattr -x $xattr $testfile ||
28286                 error "setfattr failed with $?"
28287         projid=($($LFS project $testfile))
28288         [ ${projid[0]} == "0" ] ||
28289                 error "projid expected 0 not $projid"
28290
28291         #should be hidden when parent has inherit flag and same projid
28292         $LFS project -srp 1002 $DIR/$tdir ||
28293                 error "set $tdir project id failed"
28294         getfattr -m - $testfile | grep $xattr &&
28295                 error "do not show trusted.projid with inherit flag"
28296
28297         #still can getxattr explicitly
28298         projid=$(getfattr -n $xattr $testfile |
28299                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
28300         [ $projid == "1002" ] ||
28301                 error "projid expected 1002 not $projid"
28302 }
28303 run_test 904 "virtual project ID xattr"
28304
28305 complete $SECONDS
28306 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
28307 check_and_cleanup_lustre
28308 if [ "$I_MOUNTED" != "yes" ]; then
28309         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
28310 fi
28311 exit_status