Whamcloud - gitweb
LU-14102 tests: add a pause in open-close in sanity/160l
[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 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 selinux_status=$(getenforce)
48 if [ "$selinux_status" != "Disabled" ]; then
49         # bug number:
50         ALWAYS_EXCEPT+=""
51 fi
52
53 # skip the grant tests for ARM until they are fixed
54 if [[ $(uname -m) = aarch64 ]]; then
55         # bug number:    LU-11596
56         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
57         # bug number:    LU-11671 LU-11667
58         ALWAYS_EXCEPT+=" 45       317"
59         # bug number:    LU-14067 LU-14067
60         ALWAYS_EXCEPT+=" 400a     400b"
61 fi
62
63 # skip nfs tests on kernels >= 4.12.0 until they are fixed
64 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
65         # bug number:   LU-12661
66         ALWAYS_EXCEPT+=" 817"
67 fi
68 # skip cgroup tests on RHEL8.1 kernels until they are fixed
69 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
70       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
71         # bug number:   LU-13063
72         ALWAYS_EXCEPT+=" 411"
73 fi
74
75 #                                  5          12     8   12  (min)"
76 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
77
78 if [ "$mds1_FSTYPE" = "zfs" ]; then
79         # bug number for skipped test:
80         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
81         #                                               13    (min)"
82         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
83 fi
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ]; then
101         sles_version=$(sles_version_code)
102         [ $sles_version -lt $(version_code 11.4.0) ] &&
103                 # bug number for skipped test: LU-4341
104                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
105         [ $sles_version -lt $(version_code 12.0.0) ] &&
106                 # bug number for skipped test: LU-3703
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
108 elif [ -r /etc/os-release ]; then
109         if grep -qi ubuntu /etc/os-release; then
110                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
111                                                 -e 's/^VERSION=//p' \
112                                                 /etc/os-release |
113                                                 awk '{ print $1 }'))
114
115                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
116                         # bug number for skipped test:
117                         #                LU-10334 LU-10366
118                         ALWAYS_EXCEPT+=" 103a     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:-$((200000 * $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 the value of client version
235         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
236         exp_val=$(version_code $exp_client_version)
237         imp_val=$CLIENT_VERSION
238         [ "$exp_val" == "$imp_val" ] ||
239                 error "export client version '$exp_val' != '$imp_val'"
240 }
241 run_test 0d "check export proc ============================="
242
243 test_1() {
244         test_mkdir $DIR/$tdir
245         test_mkdir $DIR/$tdir/d2
246         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
247         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
248         rmdir $DIR/$tdir/d2
249         rmdir $DIR/$tdir
250         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
251 }
252 run_test 1 "mkdir; remkdir; rmdir"
253
254 test_2() {
255         test_mkdir $DIR/$tdir
256         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
257         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
258         rm -r $DIR/$tdir
259         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
260 }
261 run_test 2 "mkdir; touch; rmdir; check file"
262
263 test_3() {
264         test_mkdir $DIR/$tdir
265         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
266         touch $DIR/$tdir/$tfile
267         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
268         rm -r $DIR/$tdir
269         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
270 }
271 run_test 3 "mkdir; touch; rmdir; check dir"
272
273 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
274 test_4() {
275         test_mkdir -i 1 $DIR/$tdir
276
277         touch $DIR/$tdir/$tfile ||
278                 error "Create file under remote directory failed"
279
280         rmdir $DIR/$tdir &&
281                 error "Expect error removing in-use dir $DIR/$tdir"
282
283         test -d $DIR/$tdir || error "Remote directory disappeared"
284
285         rm -rf $DIR/$tdir || error "remove remote dir error"
286 }
287 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
288
289 test_5() {
290         test_mkdir $DIR/$tdir
291         test_mkdir $DIR/$tdir/d2
292         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
293         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
294         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
295 }
296 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
297
298 test_6a() {
299         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
300         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
301         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
302                 error "$tfile does not have perm 0666 or UID $UID"
303         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
304         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
305                 error "$tfile should be 0666 and owned by UID $UID"
306 }
307 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
308
309 test_6c() {
310         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
311
312         touch $DIR/$tfile
313         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
314         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
315                 error "$tfile should be owned by UID $RUNAS_ID"
316         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
317         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
318                 error "$tfile should be owned by UID $RUNAS_ID"
319 }
320 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
321
322 test_6e() {
323         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
324
325         touch $DIR/$tfile
326         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
327         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
328                 error "$tfile should be owned by GID $UID"
329         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
330         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
331                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
332 }
333 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
334
335 test_6g() {
336         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
337
338         test_mkdir $DIR/$tdir
339         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
340         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
341         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
342         test_mkdir $DIR/$tdir/d/subdir
343         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
344                 error "$tdir/d/subdir should be GID $RUNAS_GID"
345         if [[ $MDSCOUNT -gt 1 ]]; then
346                 # check remote dir sgid inherite
347                 $LFS mkdir -i 0 $DIR/$tdir.local ||
348                         error "mkdir $tdir.local failed"
349                 chmod g+s $DIR/$tdir.local ||
350                         error "chmod $tdir.local failed"
351                 chgrp $RUNAS_GID $DIR/$tdir.local ||
352                         error "chgrp $tdir.local failed"
353                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
354                         error "mkdir $tdir.remote failed"
355                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
356                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
357                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
358                         error "$tdir.remote should be mode 02755"
359         fi
360 }
361 run_test 6g "verify new dir in sgid dir inherits group"
362
363 test_6h() { # bug 7331
364         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
365
366         touch $DIR/$tfile || error "touch failed"
367         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
368         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
369                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
370         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
371                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
372 }
373 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
374
375 test_7a() {
376         test_mkdir $DIR/$tdir
377         $MCREATE $DIR/$tdir/$tfile
378         chmod 0666 $DIR/$tdir/$tfile
379         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
380                 error "$tdir/$tfile should be mode 0666"
381 }
382 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
383
384 test_7b() {
385         if [ ! -d $DIR/$tdir ]; then
386                 test_mkdir $DIR/$tdir
387         fi
388         $MCREATE $DIR/$tdir/$tfile
389         echo -n foo > $DIR/$tdir/$tfile
390         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
391         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
392 }
393 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
394
395 test_8() {
396         test_mkdir $DIR/$tdir
397         touch $DIR/$tdir/$tfile
398         chmod 0666 $DIR/$tdir/$tfile
399         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
400                 error "$tfile mode not 0666"
401 }
402 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
403
404 test_9() {
405         test_mkdir $DIR/$tdir
406         test_mkdir $DIR/$tdir/d2
407         test_mkdir $DIR/$tdir/d2/d3
408         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
409 }
410 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
411
412 test_10() {
413         test_mkdir $DIR/$tdir
414         test_mkdir $DIR/$tdir/d2
415         touch $DIR/$tdir/d2/$tfile
416         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
417                 error "$tdir/d2/$tfile not a file"
418 }
419 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
420
421 test_11() {
422         test_mkdir $DIR/$tdir
423         test_mkdir $DIR/$tdir/d2
424         chmod 0666 $DIR/$tdir/d2
425         chmod 0705 $DIR/$tdir/d2
426         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
427                 error "$tdir/d2 mode not 0705"
428 }
429 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
430
431 test_12() {
432         test_mkdir $DIR/$tdir
433         touch $DIR/$tdir/$tfile
434         chmod 0666 $DIR/$tdir/$tfile
435         chmod 0654 $DIR/$tdir/$tfile
436         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
437                 error "$tdir/d2 mode not 0654"
438 }
439 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
440
441 test_13() {
442         test_mkdir $DIR/$tdir
443         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
444         >  $DIR/$tdir/$tfile
445         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
446                 error "$tdir/$tfile size not 0 after truncate"
447 }
448 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
449
450 test_14() {
451         test_mkdir $DIR/$tdir
452         touch $DIR/$tdir/$tfile
453         rm $DIR/$tdir/$tfile
454         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
455 }
456 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
457
458 test_15() {
459         test_mkdir $DIR/$tdir
460         touch $DIR/$tdir/$tfile
461         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
462         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
463                 error "$tdir/${tfile_2} not a file after rename"
464         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
465 }
466 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
467
468 test_16() {
469         test_mkdir $DIR/$tdir
470         touch $DIR/$tdir/$tfile
471         rm -rf $DIR/$tdir/$tfile
472         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
473 }
474 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
475
476 test_17a() {
477         test_mkdir $DIR/$tdir
478         touch $DIR/$tdir/$tfile
479         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
480         ls -l $DIR/$tdir
481         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
482                 error "$tdir/l-exist not a symlink"
483         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
484                 error "$tdir/l-exist not referencing a file"
485         rm -f $DIR/$tdir/l-exist
486         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
487 }
488 run_test 17a "symlinks: create, remove (real)"
489
490 test_17b() {
491         test_mkdir $DIR/$tdir
492         ln -s no-such-file $DIR/$tdir/l-dangle
493         ls -l $DIR/$tdir
494         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
495                 error "$tdir/l-dangle not referencing no-such-file"
496         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
497                 error "$tdir/l-dangle not referencing non-existent file"
498         rm -f $DIR/$tdir/l-dangle
499         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
500 }
501 run_test 17b "symlinks: create, remove (dangling)"
502
503 test_17c() { # bug 3440 - don't save failed open RPC for replay
504         test_mkdir $DIR/$tdir
505         ln -s foo $DIR/$tdir/$tfile
506         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
507 }
508 run_test 17c "symlinks: open dangling (should return error)"
509
510 test_17d() {
511         test_mkdir $DIR/$tdir
512         ln -s foo $DIR/$tdir/$tfile
513         touch $DIR/$tdir/$tfile || error "creating to new symlink"
514 }
515 run_test 17d "symlinks: create dangling"
516
517 test_17e() {
518         test_mkdir $DIR/$tdir
519         local foo=$DIR/$tdir/$tfile
520         ln -s $foo $foo || error "create symlink failed"
521         ls -l $foo || error "ls -l failed"
522         ls $foo && error "ls not failed" || true
523 }
524 run_test 17e "symlinks: create recursive symlink (should return error)"
525
526 test_17f() {
527         test_mkdir $DIR/$tdir
528         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
529         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
530         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
531         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
532         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
533         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
534         ls -l  $DIR/$tdir
535 }
536 run_test 17f "symlinks: long and very long symlink name"
537
538 # str_repeat(S, N) generate a string that is string S repeated N times
539 str_repeat() {
540         local s=$1
541         local n=$2
542         local ret=''
543         while [ $((n -= 1)) -ge 0 ]; do
544                 ret=$ret$s
545         done
546         echo $ret
547 }
548
549 # Long symlinks and LU-2241
550 test_17g() {
551         test_mkdir $DIR/$tdir
552         local TESTS="59 60 61 4094 4095"
553
554         # Fix for inode size boundary in 2.1.4
555         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
556                 TESTS="4094 4095"
557
558         # Patch not applied to 2.2 or 2.3 branches
559         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
560         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
561                 TESTS="4094 4095"
562
563         for i in $TESTS; do
564                 local SYMNAME=$(str_repeat 'x' $i)
565                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
566                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
567         done
568 }
569 run_test 17g "symlinks: really long symlink name and inode boundaries"
570
571 test_17h() { #bug 17378
572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
573         remote_mds_nodsh && skip "remote MDS with nodsh"
574
575         local mdt_idx
576
577         test_mkdir $DIR/$tdir
578         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
579         $LFS setstripe -c -1 $DIR/$tdir
580         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
581         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
582         touch $DIR/$tdir/$tfile || true
583 }
584 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
585
586 test_17i() { #bug 20018
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         remote_mds_nodsh && skip "remote MDS with nodsh"
589
590         local foo=$DIR/$tdir/$tfile
591         local mdt_idx
592
593         test_mkdir -c1 $DIR/$tdir
594         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
595         ln -s $foo $foo || error "create symlink failed"
596 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
597         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
598         ls -l $foo && error "error not detected"
599         return 0
600 }
601 run_test 17i "don't panic on short symlink (should return error)"
602
603 test_17k() { #bug 22301
604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
605         [[ -z "$(which rsync 2>/dev/null)" ]] &&
606                 skip "no rsync command"
607         rsync --help | grep -q xattr ||
608                 skip_env "$(rsync --version | head -n1) does not support xattrs"
609         test_mkdir $DIR/$tdir
610         test_mkdir $DIR/$tdir.new
611         touch $DIR/$tdir/$tfile
612         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
613         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
614                 error "rsync failed with xattrs enabled"
615 }
616 run_test 17k "symlinks: rsync with xattrs enabled"
617
618 test_17l() { # LU-279
619         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
620                 skip "no getfattr command"
621
622         test_mkdir $DIR/$tdir
623         touch $DIR/$tdir/$tfile
624         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
625         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
626                 # -h to not follow symlinks. -m '' to list all the xattrs.
627                 # grep to remove first line: '# file: $path'.
628                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
629                 do
630                         lgetxattr_size_check $path $xattr ||
631                                 error "lgetxattr_size_check $path $xattr failed"
632                 done
633         done
634 }
635 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
636
637 # LU-1540
638 test_17m() {
639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
640         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
641         remote_mds_nodsh && skip "remote MDS with nodsh"
642         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
643         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
644                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
645
646         local short_sym="0123456789"
647         local wdir=$DIR/$tdir
648         local i
649
650         test_mkdir $wdir
651         long_sym=$short_sym
652         # create a long symlink file
653         for ((i = 0; i < 4; ++i)); do
654                 long_sym=${long_sym}${long_sym}
655         done
656
657         echo "create 512 short and long symlink files under $wdir"
658         for ((i = 0; i < 256; ++i)); do
659                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
660                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
661         done
662
663         echo "erase them"
664         rm -f $wdir/*
665         sync
666         wait_delete_completed
667
668         echo "recreate the 512 symlink files with a shorter string"
669         for ((i = 0; i < 512; ++i)); do
670                 # rewrite the symlink file with a shorter string
671                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
672                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
673         done
674
675         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
676         local devname=$(mdsdevname $mds_index)
677
678         echo "stop and checking mds${mds_index}:"
679         # e2fsck should not return error
680         stop mds${mds_index}
681         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
682         rc=$?
683
684         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
685                 error "start mds${mds_index} failed"
686         df $MOUNT > /dev/null 2>&1
687         [ $rc -eq 0 ] ||
688                 error "e2fsck detected error for short/long symlink: rc=$rc"
689         rm -f $wdir/*
690 }
691 run_test 17m "run e2fsck against MDT which contains short/long symlink"
692
693 check_fs_consistency_17n() {
694         local mdt_index
695         local rc=0
696
697         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
698         # so it only check MDT1/MDT2 instead of all of MDTs.
699         for mdt_index in 1 2; do
700                 local devname=$(mdsdevname $mdt_index)
701                 # e2fsck should not return error
702                 stop mds${mdt_index}
703                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
704                         rc=$((rc + $?))
705
706                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
707                         error "mount mds$mdt_index failed"
708                 df $MOUNT > /dev/null 2>&1
709         done
710         return $rc
711 }
712
713 test_17n() {
714         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
717         remote_mds_nodsh && skip "remote MDS with nodsh"
718         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
719         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
720                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
721
722         local i
723
724         test_mkdir $DIR/$tdir
725         for ((i=0; i<10; i++)); do
726                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
727                         error "create remote dir error $i"
728                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
729                         error "create files under remote dir failed $i"
730         done
731
732         check_fs_consistency_17n ||
733                 error "e2fsck report error after create files under remote dir"
734
735         for ((i = 0; i < 10; i++)); do
736                 rm -rf $DIR/$tdir/remote_dir_${i} ||
737                         error "destroy remote dir error $i"
738         done
739
740         check_fs_consistency_17n ||
741                 error "e2fsck report error after unlink files under remote dir"
742
743         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
744                 skip "lustre < 2.4.50 does not support migrate mv"
745
746         for ((i = 0; i < 10; i++)); do
747                 mkdir -p $DIR/$tdir/remote_dir_${i}
748                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
749                         error "create files under remote dir failed $i"
750                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
751                         error "migrate remote dir error $i"
752         done
753         check_fs_consistency_17n || error "e2fsck report error after migration"
754
755         for ((i = 0; i < 10; i++)); do
756                 rm -rf $DIR/$tdir/remote_dir_${i} ||
757                         error "destroy remote dir error $i"
758         done
759
760         check_fs_consistency_17n || error "e2fsck report error after unlink"
761 }
762 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
763
764 test_17o() {
765         remote_mds_nodsh && skip "remote MDS with nodsh"
766         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
767                 skip "Need MDS version at least 2.3.64"
768
769         local wdir=$DIR/${tdir}o
770         local mdt_index
771         local rc=0
772
773         test_mkdir $wdir
774         touch $wdir/$tfile
775         mdt_index=$($LFS getstripe -m $wdir/$tfile)
776         mdt_index=$((mdt_index + 1))
777
778         cancel_lru_locks mdc
779         #fail mds will wait the failover finish then set
780         #following fail_loc to avoid interfer the recovery process.
781         fail mds${mdt_index}
782
783         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
784         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
785         ls -l $wdir/$tfile && rc=1
786         do_facet mds${mdt_index} lctl set_param fail_loc=0
787         [[ $rc -eq 0 ]] || error "stat file should fail"
788 }
789 run_test 17o "stat file with incompat LMA feature"
790
791 test_18() {
792         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
793         ls $DIR || error "Failed to ls $DIR: $?"
794 }
795 run_test 18 "touch .../f ; ls ... =============================="
796
797 test_19a() {
798         touch $DIR/$tfile
799         ls -l $DIR
800         rm $DIR/$tfile
801         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
802 }
803 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
804
805 test_19b() {
806         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
807 }
808 run_test 19b "ls -l .../f19 (should return error) =============="
809
810 test_19c() {
811         [ $RUNAS_ID -eq $UID ] &&
812                 skip_env "RUNAS_ID = UID = $UID -- skipping"
813
814         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
815 }
816 run_test 19c "$RUNAS touch .../f19 (should return error) =="
817
818 test_19d() {
819         cat $DIR/f19 && error || true
820 }
821 run_test 19d "cat .../f19 (should return error) =============="
822
823 test_20() {
824         touch $DIR/$tfile
825         rm $DIR/$tfile
826         touch $DIR/$tfile
827         rm $DIR/$tfile
828         touch $DIR/$tfile
829         rm $DIR/$tfile
830         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
831 }
832 run_test 20 "touch .../f ; ls -l ..."
833
834 test_21() {
835         test_mkdir $DIR/$tdir
836         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
837         ln -s dangle $DIR/$tdir/link
838         echo foo >> $DIR/$tdir/link
839         cat $DIR/$tdir/dangle
840         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
841         $CHECKSTAT -f -t file $DIR/$tdir/link ||
842                 error "$tdir/link not linked to a file"
843 }
844 run_test 21 "write to dangling link"
845
846 test_22() {
847         local wdir=$DIR/$tdir
848         test_mkdir $wdir
849         chown $RUNAS_ID:$RUNAS_GID $wdir
850         (cd $wdir || error "cd $wdir failed";
851                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
852                 $RUNAS tar xf -)
853         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
854         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
855         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
856                 error "checkstat -u failed"
857 }
858 run_test 22 "unpack tar archive as non-root user"
859
860 # was test_23
861 test_23a() {
862         test_mkdir $DIR/$tdir
863         local file=$DIR/$tdir/$tfile
864
865         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
866         openfile -f O_CREAT:O_EXCL $file &&
867                 error "$file recreate succeeded" || true
868 }
869 run_test 23a "O_CREAT|O_EXCL in subdir"
870
871 test_23b() { # bug 18988
872         test_mkdir $DIR/$tdir
873         local file=$DIR/$tdir/$tfile
874
875         rm -f $file
876         echo foo > $file || error "write filed"
877         echo bar >> $file || error "append filed"
878         $CHECKSTAT -s 8 $file || error "wrong size"
879         rm $file
880 }
881 run_test 23b "O_APPEND check"
882
883 # LU-9409, size with O_APPEND and tiny writes
884 test_23c() {
885         local file=$DIR/$tfile
886
887         # single dd
888         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
889         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
890         rm -f $file
891
892         # racing tiny writes
893         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
894         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
895         wait
896         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
897         rm -f $file
898
899         #racing tiny & normal writes
900         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
901         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
902         wait
903         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
904         rm -f $file
905
906         #racing tiny & normal writes 2, ugly numbers
907         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
909         wait
910         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
911         rm -f $file
912 }
913 run_test 23c "O_APPEND size checks for tiny writes"
914
915 # LU-11069 file offset is correct after appending writes
916 test_23d() {
917         local file=$DIR/$tfile
918         local offset
919
920         echo CentaurHauls > $file
921         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
922         if ((offset != 26)); then
923                 error "wrong offset, expected 26, got '$offset'"
924         fi
925 }
926 run_test 23d "file offset is correct after appending writes"
927
928 # rename sanity
929 test_24a() {
930         echo '-- same directory rename'
931         test_mkdir $DIR/$tdir
932         touch $DIR/$tdir/$tfile.1
933         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
934         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
935 }
936 run_test 24a "rename file to non-existent target"
937
938 test_24b() {
939         test_mkdir $DIR/$tdir
940         touch $DIR/$tdir/$tfile.{1,2}
941         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
942         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
943         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
944 }
945 run_test 24b "rename file to existing target"
946
947 test_24c() {
948         test_mkdir $DIR/$tdir
949         test_mkdir $DIR/$tdir/d$testnum.1
950         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
951         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
952         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
953 }
954 run_test 24c "rename directory to non-existent target"
955
956 test_24d() {
957         test_mkdir -c1 $DIR/$tdir
958         test_mkdir -c1 $DIR/$tdir/d$testnum.1
959         test_mkdir -c1 $DIR/$tdir/d$testnum.2
960         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
961         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
962         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
963 }
964 run_test 24d "rename directory to existing target"
965
966 test_24e() {
967         echo '-- cross directory renames --'
968         test_mkdir $DIR/R5a
969         test_mkdir $DIR/R5b
970         touch $DIR/R5a/f
971         mv $DIR/R5a/f $DIR/R5b/g
972         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
973         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
974 }
975 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
976
977 test_24f() {
978         test_mkdir $DIR/R6a
979         test_mkdir $DIR/R6b
980         touch $DIR/R6a/f $DIR/R6b/g
981         mv $DIR/R6a/f $DIR/R6b/g
982         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
983         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
984 }
985 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
986
987 test_24g() {
988         test_mkdir $DIR/R7a
989         test_mkdir $DIR/R7b
990         test_mkdir $DIR/R7a/d
991         mv $DIR/R7a/d $DIR/R7b/e
992         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
993         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
994 }
995 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
996
997 test_24h() {
998         test_mkdir -c1 $DIR/R8a
999         test_mkdir -c1 $DIR/R8b
1000         test_mkdir -c1 $DIR/R8a/d
1001         test_mkdir -c1 $DIR/R8b/e
1002         mrename $DIR/R8a/d $DIR/R8b/e
1003         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1004         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1005 }
1006 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1007
1008 test_24i() {
1009         echo "-- rename error cases"
1010         test_mkdir $DIR/R9
1011         test_mkdir $DIR/R9/a
1012         touch $DIR/R9/f
1013         mrename $DIR/R9/f $DIR/R9/a
1014         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1015         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1016         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1017 }
1018 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1019
1020 test_24j() {
1021         test_mkdir $DIR/R10
1022         mrename $DIR/R10/f $DIR/R10/g
1023         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1024         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1025         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1026 }
1027 run_test 24j "source does not exist ============================"
1028
1029 test_24k() {
1030         test_mkdir $DIR/R11a
1031         test_mkdir $DIR/R11a/d
1032         touch $DIR/R11a/f
1033         mv $DIR/R11a/f $DIR/R11a/d
1034         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1035         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1036 }
1037 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1038
1039 # bug 2429 - rename foo foo foo creates invalid file
1040 test_24l() {
1041         f="$DIR/f24l"
1042         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1043 }
1044 run_test 24l "Renaming a file to itself ========================"
1045
1046 test_24m() {
1047         f="$DIR/f24m"
1048         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1049         # on ext3 this does not remove either the source or target files
1050         # though the "expected" operation would be to remove the source
1051         $CHECKSTAT -t file ${f} || error "${f} missing"
1052         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1053 }
1054 run_test 24m "Renaming a file to a hard link to itself ========="
1055
1056 test_24n() {
1057     f="$DIR/f24n"
1058     # this stats the old file after it was renamed, so it should fail
1059     touch ${f}
1060     $CHECKSTAT ${f} || error "${f} missing"
1061     mv ${f} ${f}.rename
1062     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1063     $CHECKSTAT -a ${f} || error "${f} exists"
1064 }
1065 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1066
1067 test_24o() {
1068         test_mkdir $DIR/$tdir
1069         rename_many -s random -v -n 10 $DIR/$tdir
1070 }
1071 run_test 24o "rename of files during htree split"
1072
1073 test_24p() {
1074         test_mkdir $DIR/R12a
1075         test_mkdir $DIR/R12b
1076         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1077         mrename $DIR/R12a $DIR/R12b
1078         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1079         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1080         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1081         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1082 }
1083 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1084
1085 cleanup_multiop_pause() {
1086         trap 0
1087         kill -USR1 $MULTIPID
1088 }
1089
1090 test_24q() {
1091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1092
1093         test_mkdir $DIR/R13a
1094         test_mkdir $DIR/R13b
1095         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1096         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1097         MULTIPID=$!
1098
1099         trap cleanup_multiop_pause EXIT
1100         mrename $DIR/R13a $DIR/R13b
1101         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1102         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1103         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1104         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1105         cleanup_multiop_pause
1106         wait $MULTIPID || error "multiop close failed"
1107 }
1108 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1109
1110 test_24r() { #bug 3789
1111         test_mkdir $DIR/R14a
1112         test_mkdir $DIR/R14a/b
1113         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1114         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1115         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1116 }
1117 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1118
1119 test_24s() {
1120         test_mkdir $DIR/R15a
1121         test_mkdir $DIR/R15a/b
1122         test_mkdir $DIR/R15a/b/c
1123         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1124         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1125         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1126 }
1127 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1128 test_24t() {
1129         test_mkdir $DIR/R16a
1130         test_mkdir $DIR/R16a/b
1131         test_mkdir $DIR/R16a/b/c
1132         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1133         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1134         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1135 }
1136 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1137
1138 test_24u() { # bug12192
1139         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1140         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1141 }
1142 run_test 24u "create stripe file"
1143
1144 simple_cleanup_common() {
1145         local rc=0
1146         trap 0
1147         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1148
1149         local start=$SECONDS
1150         rm -rf $DIR/$tdir
1151         rc=$?
1152         wait_delete_completed
1153         echo "cleanup time $((SECONDS - start))"
1154         return $rc
1155 }
1156
1157 max_pages_per_rpc() {
1158         local mdtname="$(printf "MDT%04x" ${1:-0})"
1159         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1160 }
1161
1162 test_24v() {
1163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1164
1165         local nrfiles=${COUNT:-100000}
1166         local fname="$DIR/$tdir/$tfile"
1167
1168         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1169         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1170
1171         test_mkdir "$(dirname $fname)"
1172         # assume MDT0000 has the fewest inodes
1173         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1174         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1175         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1176
1177         trap simple_cleanup_common EXIT
1178
1179         createmany -m "$fname" $nrfiles
1180
1181         cancel_lru_locks mdc
1182         lctl set_param mdc.*.stats clear
1183
1184         # was previously test_24D: LU-6101
1185         # readdir() returns correct number of entries after cursor reload
1186         local num_ls=$(ls $DIR/$tdir | wc -l)
1187         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1188         local num_all=$(ls -a $DIR/$tdir | wc -l)
1189         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1190                 [ $num_all -ne $((nrfiles + 2)) ]; then
1191                         error "Expected $nrfiles files, got $num_ls " \
1192                                 "($num_uniq unique $num_all .&..)"
1193         fi
1194         # LU-5 large readdir
1195         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1196         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1197         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1198         # take into account of overhead in lu_dirpage header and end mark in
1199         # each page, plus one in rpc_num calculation.
1200         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1201         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1202         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1203         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1204         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1205         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1206         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1207         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1208                 error "large readdir doesn't take effect: " \
1209                       "$mds_readpage should be about $rpc_max"
1210
1211         simple_cleanup_common
1212 }
1213 run_test 24v "list large directory (test hash collision, b=17560)"
1214
1215 test_24w() { # bug21506
1216         SZ1=234852
1217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1218         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1219         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1220         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1221         [[ "$SZ1" -eq "$SZ2" ]] ||
1222                 error "Error reading at the end of the file $tfile"
1223 }
1224 run_test 24w "Reading a file larger than 4Gb"
1225
1226 test_24x() {
1227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1229         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1230                 skip "Need MDS version at least 2.7.56"
1231
1232         local MDTIDX=1
1233         local remote_dir=$DIR/$tdir/remote_dir
1234
1235         test_mkdir $DIR/$tdir
1236         $LFS mkdir -i $MDTIDX $remote_dir ||
1237                 error "create remote directory failed"
1238
1239         test_mkdir $DIR/$tdir/src_dir
1240         touch $DIR/$tdir/src_file
1241         test_mkdir $remote_dir/tgt_dir
1242         touch $remote_dir/tgt_file
1243
1244         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1245                 error "rename dir cross MDT failed!"
1246
1247         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1248                 error "rename file cross MDT failed!"
1249
1250         touch $DIR/$tdir/ln_file
1251         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1252                 error "ln file cross MDT failed"
1253
1254         rm -rf $DIR/$tdir || error "Can not delete directories"
1255 }
1256 run_test 24x "cross MDT rename/link"
1257
1258 test_24y() {
1259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1261
1262         local remote_dir=$DIR/$tdir/remote_dir
1263         local mdtidx=1
1264
1265         test_mkdir $DIR/$tdir
1266         $LFS mkdir -i $mdtidx $remote_dir ||
1267                 error "create remote directory failed"
1268
1269         test_mkdir $remote_dir/src_dir
1270         touch $remote_dir/src_file
1271         test_mkdir $remote_dir/tgt_dir
1272         touch $remote_dir/tgt_file
1273
1274         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1275                 error "rename subdir in the same remote dir failed!"
1276
1277         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1278                 error "rename files in the same remote dir failed!"
1279
1280         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1281                 error "link files in the same remote dir failed!"
1282
1283         rm -rf $DIR/$tdir || error "Can not delete directories"
1284 }
1285 run_test 24y "rename/link on the same dir should succeed"
1286
1287 test_24z() {
1288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1289         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1290                 skip "Need MDS version at least 2.12.51"
1291
1292         local index
1293
1294         for index in 0 1; do
1295                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1296                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1297         done
1298
1299         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1300
1301         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1302         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1303
1304         local mdts=$(comma_list $(mdts_nodes))
1305
1306         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1307         stack_trap "do_nodes $mdts $LCTL \
1308                 set_param mdt.*.enable_remote_rename=1" EXIT
1309
1310         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1313         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1314 }
1315 run_test 24z "cross-MDT rename is done as cp"
1316
1317 test_24A() { # LU-3182
1318         local NFILES=5000
1319
1320         rm -rf $DIR/$tdir
1321         test_mkdir $DIR/$tdir
1322         trap simple_cleanup_common EXIT
1323         createmany -m $DIR/$tdir/$tfile $NFILES
1324         local t=$(ls $DIR/$tdir | wc -l)
1325         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1326         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1327         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1328            [ $v -ne $((NFILES + 2)) ] ; then
1329                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1330         fi
1331
1332         simple_cleanup_common || error "Can not delete directories"
1333 }
1334 run_test 24A "readdir() returns correct number of entries."
1335
1336 test_24B() { # LU-4805
1337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1338
1339         local count
1340
1341         test_mkdir $DIR/$tdir
1342         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1343                 error "create striped dir failed"
1344
1345         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1346         [ $count -eq 2 ] || error "Expected 2, got $count"
1347
1348         touch $DIR/$tdir/striped_dir/a
1349
1350         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1351         [ $count -eq 3 ] || error "Expected 3, got $count"
1352
1353         touch $DIR/$tdir/striped_dir/.f
1354
1355         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1356         [ $count -eq 4 ] || error "Expected 4, got $count"
1357
1358         rm -rf $DIR/$tdir || error "Can not delete directories"
1359 }
1360 run_test 24B "readdir for striped dir return correct number of entries"
1361
1362 test_24C() {
1363         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1364
1365         mkdir $DIR/$tdir
1366         mkdir $DIR/$tdir/d0
1367         mkdir $DIR/$tdir/d1
1368
1369         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1370                 error "create striped dir failed"
1371
1372         cd $DIR/$tdir/d0/striped_dir
1373
1374         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1375         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1376         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1377
1378         [ "$d0_ino" = "$parent_ino" ] ||
1379                 error ".. wrong, expect $d0_ino, get $parent_ino"
1380
1381         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1382                 error "mv striped dir failed"
1383
1384         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1385
1386         [ "$d1_ino" = "$parent_ino" ] ||
1387                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1388 }
1389 run_test 24C "check .. in striped dir"
1390
1391 test_24E() {
1392         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1394
1395         mkdir -p $DIR/$tdir
1396         mkdir $DIR/$tdir/src_dir
1397         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1398                 error "create remote source failed"
1399
1400         touch $DIR/$tdir/src_dir/src_child/a
1401
1402         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1403                 error "create remote target dir failed"
1404
1405         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1406                 error "create remote target child failed"
1407
1408         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "rename dir cross MDT failed!"
1410
1411         find $DIR/$tdir
1412
1413         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1414                 error "src_child still exists after rename"
1415
1416         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1417                 error "missing file(a) after rename"
1418
1419         rm -rf $DIR/$tdir || error "Can not delete directories"
1420 }
1421 run_test 24E "cross MDT rename/link"
1422
1423 test_24F () {
1424         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1425
1426         local repeats=1000
1427         [ "$SLOW" = "no" ] && repeats=100
1428
1429         mkdir -p $DIR/$tdir
1430
1431         echo "$repeats repeats"
1432         for ((i = 0; i < repeats; i++)); do
1433                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1434                 touch $DIR/$tdir/test/a || error "touch fails"
1435                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1436                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1437         done
1438
1439         true
1440 }
1441 run_test 24F "hash order vs readdir (LU-11330)"
1442
1443 test_24G () {
1444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1445
1446         local ino1
1447         local ino2
1448
1449         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1450         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1451         touch $DIR/$tdir-0/f1 || error "touch f1"
1452         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1453         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1454         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1455         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1456         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1457 }
1458 run_test 24G "migrate symlink in rename"
1459
1460 test_25a() {
1461         echo '== symlink sanity ============================================='
1462
1463         test_mkdir $DIR/d25
1464         ln -s d25 $DIR/s25
1465         touch $DIR/s25/foo ||
1466                 error "File creation in symlinked directory failed"
1467 }
1468 run_test 25a "create file in symlinked directory ==============="
1469
1470 test_25b() {
1471         [ ! -d $DIR/d25 ] && test_25a
1472         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1473 }
1474 run_test 25b "lookup file in symlinked directory ==============="
1475
1476 test_26a() {
1477         test_mkdir $DIR/d26
1478         test_mkdir $DIR/d26/d26-2
1479         ln -s d26/d26-2 $DIR/s26
1480         touch $DIR/s26/foo || error "File creation failed"
1481 }
1482 run_test 26a "multiple component symlink ======================="
1483
1484 test_26b() {
1485         test_mkdir -p $DIR/$tdir/d26-2
1486         ln -s $tdir/d26-2/foo $DIR/s26-2
1487         touch $DIR/s26-2 || error "File creation failed"
1488 }
1489 run_test 26b "multiple component symlink at end of lookup ======"
1490
1491 test_26c() {
1492         test_mkdir $DIR/d26.2
1493         touch $DIR/d26.2/foo
1494         ln -s d26.2 $DIR/s26.2-1
1495         ln -s s26.2-1 $DIR/s26.2-2
1496         ln -s s26.2-2 $DIR/s26.2-3
1497         chmod 0666 $DIR/s26.2-3/foo
1498 }
1499 run_test 26c "chain of symlinks"
1500
1501 # recursive symlinks (bug 439)
1502 test_26d() {
1503         ln -s d26-3/foo $DIR/d26-3
1504 }
1505 run_test 26d "create multiple component recursive symlink"
1506
1507 test_26e() {
1508         [ ! -h $DIR/d26-3 ] && test_26d
1509         rm $DIR/d26-3
1510 }
1511 run_test 26e "unlink multiple component recursive symlink"
1512
1513 # recursive symlinks (bug 7022)
1514 test_26f() {
1515         test_mkdir $DIR/$tdir
1516         test_mkdir $DIR/$tdir/$tfile
1517         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1518         test_mkdir -p lndir/bar1
1519         test_mkdir $DIR/$tdir/$tfile/$tfile
1520         cd $tfile                || error "cd $tfile failed"
1521         ln -s .. dotdot          || error "ln dotdot failed"
1522         ln -s dotdot/lndir lndir || error "ln lndir failed"
1523         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1524         output=`ls $tfile/$tfile/lndir/bar1`
1525         [ "$output" = bar1 ] && error "unexpected output"
1526         rm -r $tfile             || error "rm $tfile failed"
1527         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1528 }
1529 run_test 26f "rm -r of a directory which has recursive symlink"
1530
1531 test_27a() {
1532         test_mkdir $DIR/$tdir
1533         $LFS getstripe $DIR/$tdir
1534         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1535         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1536         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1537 }
1538 run_test 27a "one stripe file"
1539
1540 test_27b() {
1541         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1542
1543         test_mkdir $DIR/$tdir
1544         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1545         $LFS getstripe -c $DIR/$tdir/$tfile
1546         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1547                 error "two-stripe file doesn't have two stripes"
1548
1549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1550 }
1551 run_test 27b "create and write to two stripe file"
1552
1553 # 27c family tests specific striping, setstripe -o
1554 test_27ca() {
1555         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1556         test_mkdir -p $DIR/$tdir
1557         local osts="1"
1558
1559         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1560         $LFS getstripe -i $DIR/$tdir/$tfile
1561         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1562                 error "stripe not on specified OST"
1563
1564         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1565 }
1566 run_test 27ca "one stripe on specified OST"
1567
1568 test_27cb() {
1569         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1570         test_mkdir -p $DIR/$tdir
1571         local osts="1,0"
1572         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1573         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1574         echo "$getstripe"
1575
1576         # Strip getstripe output to a space separated list of OSTs
1577         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1578                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1579         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1580                 error "stripes not on specified OSTs"
1581
1582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1583 }
1584 run_test 27cb "two stripes on specified OSTs"
1585
1586 test_27cc() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1589                 skip "server does not support overstriping"
1590
1591         test_mkdir -p $DIR/$tdir
1592         local osts="0,0"
1593         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1594         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1595         echo "$getstripe"
1596
1597         # Strip getstripe output to a space separated list of OSTs
1598         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1599                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1600         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1601                 error "stripes not on specified OSTs"
1602
1603         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1604 }
1605 run_test 27cc "two stripes on the same OST"
1606
1607 test_27cd() {
1608         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1609         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1610                 skip "server does not support overstriping"
1611         test_mkdir -p $DIR/$tdir
1612         local osts="0,1,1,0"
1613         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1614         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1615         echo "$getstripe"
1616
1617         # Strip getstripe output to a space separated list of OSTs
1618         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1619                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1620         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1621                 error "stripes not on specified OSTs"
1622
1623         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1624 }
1625 run_test 27cd "four stripes on two OSTs"
1626
1627 test_27ce() {
1628         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1629                 skip_env "too many osts, skipping"
1630         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1631                 skip "server does not support overstriping"
1632         # We do one more stripe than we have OSTs
1633         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1634                 skip_env "ea_inode feature disabled"
1635
1636         test_mkdir -p $DIR/$tdir
1637         local osts=""
1638         for i in $(seq 0 $OSTCOUNT);
1639         do
1640                 osts=$osts"0"
1641                 if [ $i -ne $OSTCOUNT ]; then
1642                         osts=$osts","
1643                 fi
1644         done
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27ce "more stripes than OSTs with -o"
1658
1659 test_27cf() {
1660         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1661         local pid=0
1662
1663         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1664         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1665         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1666         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1667                 error "failed to set $osp_proc=0"
1668
1669         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1670         pid=$!
1671         sleep 1
1672         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1673         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1674                 error "failed to set $osp_proc=1"
1675         wait $pid
1676         [[ $pid -ne 0 ]] ||
1677                 error "should return error due to $osp_proc=0"
1678 }
1679 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1680
1681 test_27d() {
1682         test_mkdir $DIR/$tdir
1683         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1684                 error "setstripe failed"
1685         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1686         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1687 }
1688 run_test 27d "create file with default settings"
1689
1690 test_27e() {
1691         # LU-5839 adds check for existed layout before setting it
1692         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1693                 skip "Need MDS version at least 2.7.56"
1694
1695         test_mkdir $DIR/$tdir
1696         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1697         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1698         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1699 }
1700 run_test 27e "setstripe existing file (should return error)"
1701
1702 test_27f() {
1703         test_mkdir $DIR/$tdir
1704         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1705                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1706         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1707                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1708         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1709         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1710 }
1711 run_test 27f "setstripe with bad stripe size (should return error)"
1712
1713 test_27g() {
1714         test_mkdir $DIR/$tdir
1715         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1716         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1717                 error "$DIR/$tdir/$tfile has object"
1718 }
1719 run_test 27g "$LFS getstripe with no objects"
1720
1721 test_27ga() {
1722         test_mkdir $DIR/$tdir
1723         touch $DIR/$tdir/$tfile || error "touch failed"
1724         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1725         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1726         local rc=$?
1727         (( rc == 2 )) || error "getstripe did not return ENOENT"
1728 }
1729 run_test 27ga "$LFS getstripe with missing file (should return error)"
1730
1731 test_27i() {
1732         test_mkdir $DIR/$tdir
1733         touch $DIR/$tdir/$tfile || error "touch failed"
1734         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1735                 error "missing objects"
1736 }
1737 run_test 27i "$LFS getstripe with some objects"
1738
1739 test_27j() {
1740         test_mkdir $DIR/$tdir
1741         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1742                 error "setstripe failed" || true
1743 }
1744 run_test 27j "setstripe with bad stripe offset (should return error)"
1745
1746 test_27k() { # bug 2844
1747         test_mkdir $DIR/$tdir
1748         local file=$DIR/$tdir/$tfile
1749         local ll_max_blksize=$((4 * 1024 * 1024))
1750         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1751         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1752         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1753         dd if=/dev/zero of=$file bs=4k count=1
1754         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1755         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1756 }
1757 run_test 27k "limit i_blksize for broken user apps"
1758
1759 test_27l() {
1760         mcreate $DIR/$tfile || error "creating file"
1761         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1762                 error "setstripe should have failed" || true
1763 }
1764 run_test 27l "check setstripe permissions (should return error)"
1765
1766 test_27m() {
1767         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1768
1769         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1770                 skip_env "multiple clients -- skipping"
1771
1772         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1773                    head -n1)
1774         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1775                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1776         fi
1777         trap simple_cleanup_common EXIT
1778         test_mkdir $DIR/$tdir
1779         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1780         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1781                 error "dd should fill OST0"
1782         i=2
1783         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1784                 i=$((i + 1))
1785                 [ $i -gt 256 ] && break
1786         done
1787         i=$((i + 1))
1788         touch $DIR/$tdir/$tfile.$i
1789         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1790             awk '{print $1}'| grep -w "0") ] &&
1791                 error "OST0 was full but new created file still use it"
1792         i=$((i + 1))
1793         touch $DIR/$tdir/$tfile.$i
1794         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1795             awk '{print $1}'| grep -w "0") ] &&
1796                 error "OST0 was full but new created file still use it"
1797         simple_cleanup_common
1798 }
1799 run_test 27m "create file while OST0 was full"
1800
1801 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1802 # if the OST isn't full anymore.
1803 reset_enospc() {
1804         local ostidx=${1:-""}
1805         local delay
1806         local ready
1807         local get_prealloc
1808
1809         local list=$(comma_list $(osts_nodes))
1810         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1811
1812         do_nodes $list lctl set_param fail_loc=0
1813         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1814         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1815                 awk '{print $1 * 2;exit;}')
1816         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1817                         grep -v \"^0$\""
1818         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1819 }
1820
1821 __exhaust_precreations() {
1822         local OSTIDX=$1
1823         local FAILLOC=$2
1824         local FAILIDX=${3:-$OSTIDX}
1825         local ofacet=ost$((OSTIDX + 1))
1826
1827         test_mkdir -p -c1 $DIR/$tdir
1828         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1829         local mfacet=mds$((mdtidx + 1))
1830         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1831
1832         local OST=$(ostname_from_index $OSTIDX)
1833
1834         # on the mdt's osc
1835         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1836         local last_id=$(do_facet $mfacet lctl get_param -n \
1837                         osp.$mdtosc_proc1.prealloc_last_id)
1838         local next_id=$(do_facet $mfacet lctl get_param -n \
1839                         osp.$mdtosc_proc1.prealloc_next_id)
1840
1841         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1842         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1843
1844         test_mkdir -p $DIR/$tdir/${OST}
1845         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1846 #define OBD_FAIL_OST_ENOSPC              0x215
1847         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1848         echo "Creating to objid $last_id on ost $OST..."
1849         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1850         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1851         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1852 }
1853
1854 exhaust_precreations() {
1855         __exhaust_precreations $1 $2 $3
1856         sleep_maxage
1857 }
1858
1859 exhaust_all_precreations() {
1860         local i
1861         for (( i=0; i < OSTCOUNT; i++ )) ; do
1862                 __exhaust_precreations $i $1 -1
1863         done
1864         sleep_maxage
1865 }
1866
1867 test_27n() {
1868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1870         remote_mds_nodsh && skip "remote MDS with nodsh"
1871         remote_ost_nodsh && skip "remote OST with nodsh"
1872
1873         reset_enospc
1874         rm -f $DIR/$tdir/$tfile
1875         exhaust_precreations 0 0x80000215
1876         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1877         touch $DIR/$tdir/$tfile || error "touch failed"
1878         $LFS getstripe $DIR/$tdir/$tfile
1879         reset_enospc
1880 }
1881 run_test 27n "create file with some full OSTs"
1882
1883 test_27o() {
1884         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1886         remote_mds_nodsh && skip "remote MDS with nodsh"
1887         remote_ost_nodsh && skip "remote OST with nodsh"
1888
1889         reset_enospc
1890         rm -f $DIR/$tdir/$tfile
1891         exhaust_all_precreations 0x215
1892
1893         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1894
1895         reset_enospc
1896         rm -rf $DIR/$tdir/*
1897 }
1898 run_test 27o "create file with all full OSTs (should error)"
1899
1900 test_27p() {
1901         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1903         remote_mds_nodsh && skip "remote MDS with nodsh"
1904         remote_ost_nodsh && skip "remote OST with nodsh"
1905
1906         reset_enospc
1907         rm -f $DIR/$tdir/$tfile
1908         test_mkdir $DIR/$tdir
1909
1910         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1911         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1912         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1913
1914         exhaust_precreations 0 0x80000215
1915         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1916         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1917         $LFS getstripe $DIR/$tdir/$tfile
1918
1919         reset_enospc
1920 }
1921 run_test 27p "append to a truncated file with some full OSTs"
1922
1923 test_27q() {
1924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1926         remote_mds_nodsh && skip "remote MDS with nodsh"
1927         remote_ost_nodsh && skip "remote OST with nodsh"
1928
1929         reset_enospc
1930         rm -f $DIR/$tdir/$tfile
1931
1932         test_mkdir $DIR/$tdir
1933         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1934         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1935                 error "truncate $DIR/$tdir/$tfile failed"
1936         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1937
1938         exhaust_all_precreations 0x215
1939
1940         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1941         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1942
1943         reset_enospc
1944 }
1945 run_test 27q "append to truncated file with all OSTs full (should error)"
1946
1947 test_27r() {
1948         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1950         remote_mds_nodsh && skip "remote MDS with nodsh"
1951         remote_ost_nodsh && skip "remote OST with nodsh"
1952
1953         reset_enospc
1954         rm -f $DIR/$tdir/$tfile
1955         exhaust_precreations 0 0x80000215
1956
1957         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1958
1959         reset_enospc
1960 }
1961 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1962
1963 test_27s() { # bug 10725
1964         test_mkdir $DIR/$tdir
1965         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1966         local stripe_count=0
1967         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1968         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1969                 error "stripe width >= 2^32 succeeded" || true
1970
1971 }
1972 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1973
1974 test_27t() { # bug 10864
1975         WDIR=$(pwd)
1976         WLFS=$(which lfs)
1977         cd $DIR
1978         touch $tfile
1979         $WLFS getstripe $tfile
1980         cd $WDIR
1981 }
1982 run_test 27t "check that utils parse path correctly"
1983
1984 test_27u() { # bug 4900
1985         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1986         remote_mds_nodsh && skip "remote MDS with nodsh"
1987
1988         local index
1989         local list=$(comma_list $(mdts_nodes))
1990
1991 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1992         do_nodes $list $LCTL set_param fail_loc=0x139
1993         test_mkdir -p $DIR/$tdir
1994         trap simple_cleanup_common EXIT
1995         createmany -o $DIR/$tdir/t- 1000
1996         do_nodes $list $LCTL set_param fail_loc=0
1997
1998         TLOG=$TMP/$tfile.getstripe
1999         $LFS getstripe $DIR/$tdir > $TLOG
2000         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2001         unlinkmany $DIR/$tdir/t- 1000
2002         trap 0
2003         [[ $OBJS -gt 0 ]] &&
2004                 error "$OBJS objects created on OST-0. See $TLOG" ||
2005                 rm -f $TLOG
2006 }
2007 run_test 27u "skip object creation on OSC w/o objects"
2008
2009 test_27v() { # bug 4900
2010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2012         remote_mds_nodsh && skip "remote MDS with nodsh"
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014
2015         exhaust_all_precreations 0x215
2016         reset_enospc
2017
2018         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2019
2020         touch $DIR/$tdir/$tfile
2021         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2022         # all except ost1
2023         for (( i=1; i < OSTCOUNT; i++ )); do
2024                 do_facet ost$i lctl set_param fail_loc=0x705
2025         done
2026         local START=`date +%s`
2027         createmany -o $DIR/$tdir/$tfile 32
2028
2029         local FINISH=`date +%s`
2030         local TIMEOUT=`lctl get_param -n timeout`
2031         local PROCESS=$((FINISH - START))
2032         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2033                error "$FINISH - $START >= $TIMEOUT / 2"
2034         sleep $((TIMEOUT / 2 - PROCESS))
2035         reset_enospc
2036 }
2037 run_test 27v "skip object creation on slow OST"
2038
2039 test_27w() { # bug 10997
2040         test_mkdir $DIR/$tdir
2041         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2042         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2043                 error "stripe size $size != 65536" || true
2044         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2045                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2046 }
2047 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2048
2049 test_27wa() {
2050         [[ $OSTCOUNT -lt 2 ]] &&
2051                 skip_env "skipping multiple stripe count/offset test"
2052
2053         test_mkdir $DIR/$tdir
2054         for i in $(seq 1 $OSTCOUNT); do
2055                 offset=$((i - 1))
2056                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2057                         error "setstripe -c $i -i $offset failed"
2058                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2059                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2060                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2061                 [ $index -ne $offset ] &&
2062                         error "stripe offset $index != $offset" || true
2063         done
2064 }
2065 run_test 27wa "check $LFS setstripe -c -i options"
2066
2067 test_27x() {
2068         remote_ost_nodsh && skip "remote OST with nodsh"
2069         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2071
2072         OFFSET=$(($OSTCOUNT - 1))
2073         OSTIDX=0
2074         local OST=$(ostname_from_index $OSTIDX)
2075
2076         test_mkdir $DIR/$tdir
2077         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2078         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2079         sleep_maxage
2080         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2081         for i in $(seq 0 $OFFSET); do
2082                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2083                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2084                 error "OST0 was degraded but new created file still use it"
2085         done
2086         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2087 }
2088 run_test 27x "create files while OST0 is degraded"
2089
2090 test_27y() {
2091         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2092         remote_mds_nodsh && skip "remote MDS with nodsh"
2093         remote_ost_nodsh && skip "remote OST with nodsh"
2094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2095
2096         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2097         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2098                 osp.$mdtosc.prealloc_last_id)
2099         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2100                 osp.$mdtosc.prealloc_next_id)
2101         local fcount=$((last_id - next_id))
2102         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2103         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2104
2105         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2106                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2107         local OST_DEACTIVE_IDX=-1
2108         local OSC
2109         local OSTIDX
2110         local OST
2111
2112         for OSC in $MDS_OSCS; do
2113                 OST=$(osc_to_ost $OSC)
2114                 OSTIDX=$(index_from_ostuuid $OST)
2115                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2116                         OST_DEACTIVE_IDX=$OSTIDX
2117                 fi
2118                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2119                         echo $OSC "is Deactivated:"
2120                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2121                 fi
2122         done
2123
2124         OSTIDX=$(index_from_ostuuid $OST)
2125         test_mkdir $DIR/$tdir
2126         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2127
2128         for OSC in $MDS_OSCS; do
2129                 OST=$(osc_to_ost $OSC)
2130                 OSTIDX=$(index_from_ostuuid $OST)
2131                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2132                         echo $OST "is degraded:"
2133                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2134                                                 obdfilter.$OST.degraded=1
2135                 fi
2136         done
2137
2138         sleep_maxage
2139         createmany -o $DIR/$tdir/$tfile $fcount
2140
2141         for OSC in $MDS_OSCS; do
2142                 OST=$(osc_to_ost $OSC)
2143                 OSTIDX=$(index_from_ostuuid $OST)
2144                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2145                         echo $OST "is recovered from degraded:"
2146                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2147                                                 obdfilter.$OST.degraded=0
2148                 else
2149                         do_facet $SINGLEMDS lctl --device %$OSC activate
2150                 fi
2151         done
2152
2153         # all osp devices get activated, hence -1 stripe count restored
2154         local stripe_count=0
2155
2156         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2157         # devices get activated.
2158         sleep_maxage
2159         $LFS setstripe -c -1 $DIR/$tfile
2160         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2161         rm -f $DIR/$tfile
2162         [ $stripe_count -ne $OSTCOUNT ] &&
2163                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2164         return 0
2165 }
2166 run_test 27y "create files while OST0 is degraded and the rest inactive"
2167
2168 check_seq_oid()
2169 {
2170         log "check file $1"
2171
2172         lmm_count=$($LFS getstripe -c $1)
2173         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2174         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2175
2176         local old_ifs="$IFS"
2177         IFS=$'[:]'
2178         fid=($($LFS path2fid $1))
2179         IFS="$old_ifs"
2180
2181         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2182         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2183
2184         # compare lmm_seq and lu_fid->f_seq
2185         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2186         # compare lmm_object_id and lu_fid->oid
2187         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2188
2189         # check the trusted.fid attribute of the OST objects of the file
2190         local have_obdidx=false
2191         local stripe_nr=0
2192         $LFS getstripe $1 | while read obdidx oid hex seq; do
2193                 # skip lines up to and including "obdidx"
2194                 [ -z "$obdidx" ] && break
2195                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2196                 $have_obdidx || continue
2197
2198                 local ost=$((obdidx + 1))
2199                 local dev=$(ostdevname $ost)
2200                 local oid_hex
2201
2202                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2203
2204                 seq=$(echo $seq | sed -e "s/^0x//g")
2205                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2206                         oid_hex=$(echo $oid)
2207                 else
2208                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2209                 fi
2210                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2211
2212                 local ff=""
2213                 #
2214                 # Don't unmount/remount the OSTs if we don't need to do that.
2215                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2216                 # update too, until that use mount/ll_decode_filter_fid/mount.
2217                 # Re-enable when debugfs will understand new filter_fid.
2218                 #
2219                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2220                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2221                                 $dev 2>/dev/null" | grep "parent=")
2222                 fi
2223                 if [ -z "$ff" ]; then
2224                         stop ost$ost
2225                         mount_fstype ost$ost
2226                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2227                                 $(facet_mntpt ost$ost)/$obj_file)
2228                         unmount_fstype ost$ost
2229                         start ost$ost $dev $OST_MOUNT_OPTS
2230                         clients_up
2231                 fi
2232
2233                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2234
2235                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2236
2237                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2238                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2239                 #
2240                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2241                 #       stripe_size=1048576 component_id=1 component_start=0 \
2242                 #       component_end=33554432
2243                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2244                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2245                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2246                 local ff_pstripe
2247                 if grep -q 'stripe=' <<<$ff; then
2248                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2249                 else
2250                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2251                         # into f_ver in this case.  See comment on ff_parent.
2252                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2253                 fi
2254
2255                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2256                 [ $ff_pseq = $lmm_seq ] ||
2257                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2258                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2259                 [ $ff_poid = $lmm_oid ] ||
2260                         error "FF parent OID $ff_poid != $lmm_oid"
2261                 (($ff_pstripe == $stripe_nr)) ||
2262                         error "FF stripe $ff_pstripe != $stripe_nr"
2263
2264                 stripe_nr=$((stripe_nr + 1))
2265                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2266                         continue
2267                 if grep -q 'stripe_count=' <<<$ff; then
2268                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2269                                             -e 's/ .*//' <<<$ff)
2270                         [ $lmm_count = $ff_scnt ] ||
2271                                 error "FF stripe count $lmm_count != $ff_scnt"
2272                 fi
2273         done
2274 }
2275
2276 test_27z() {
2277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2278         remote_ost_nodsh && skip "remote OST with nodsh"
2279
2280         test_mkdir $DIR/$tdir
2281         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2282                 { error "setstripe -c -1 failed"; return 1; }
2283         # We need to send a write to every object to get parent FID info set.
2284         # This _should_ also work for setattr, but does not currently.
2285         # touch $DIR/$tdir/$tfile-1 ||
2286         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2287                 { error "dd $tfile-1 failed"; return 2; }
2288         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2289                 { error "setstripe -c -1 failed"; return 3; }
2290         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2291                 { error "dd $tfile-2 failed"; return 4; }
2292
2293         # make sure write RPCs have been sent to OSTs
2294         sync; sleep 5; sync
2295
2296         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2297         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2298 }
2299 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2300
2301 test_27A() { # b=19102
2302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2303
2304         save_layout_restore_at_exit $MOUNT
2305         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2306         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2307                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2308         local default_size=$($LFS getstripe -S $MOUNT)
2309         local default_offset=$($LFS getstripe -i $MOUNT)
2310         local dsize=$(do_facet $SINGLEMDS \
2311                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2312         [ $default_size -eq $dsize ] ||
2313                 error "stripe size $default_size != $dsize"
2314         [ $default_offset -eq -1 ] ||
2315                 error "stripe offset $default_offset != -1"
2316 }
2317 run_test 27A "check filesystem-wide default LOV EA values"
2318
2319 test_27B() { # LU-2523
2320         test_mkdir $DIR/$tdir
2321         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2322         touch $DIR/$tdir/f0
2323         # open f1 with O_LOV_DELAY_CREATE
2324         # rename f0 onto f1
2325         # call setstripe ioctl on open file descriptor for f1
2326         # close
2327         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2328                 $DIR/$tdir/f0
2329
2330         rm -f $DIR/$tdir/f1
2331         # open f1 with O_LOV_DELAY_CREATE
2332         # unlink f1
2333         # call setstripe ioctl on open file descriptor for f1
2334         # close
2335         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2336
2337         # Allow multiop to fail in imitation of NFS's busted semantics.
2338         true
2339 }
2340 run_test 27B "call setstripe on open unlinked file/rename victim"
2341
2342 # 27C family tests full striping and overstriping
2343 test_27Ca() { #LU-2871
2344         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2345
2346         declare -a ost_idx
2347         local index
2348         local found
2349         local i
2350         local j
2351
2352         test_mkdir $DIR/$tdir
2353         cd $DIR/$tdir
2354         for i in $(seq 0 $((OSTCOUNT - 1))); do
2355                 # set stripe across all OSTs starting from OST$i
2356                 $LFS setstripe -i $i -c -1 $tfile$i
2357                 # get striping information
2358                 ost_idx=($($LFS getstripe $tfile$i |
2359                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2360                 echo ${ost_idx[@]}
2361
2362                 # check the layout
2363                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2364                         error "${#ost_idx[@]} != $OSTCOUNT"
2365
2366                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2367                         found=0
2368                         for j in $(echo ${ost_idx[@]}); do
2369                                 if [ $index -eq $j ]; then
2370                                         found=1
2371                                         break
2372                                 fi
2373                         done
2374                         [ $found = 1 ] ||
2375                                 error "Can not find $index in ${ost_idx[@]}"
2376                 done
2377         done
2378 }
2379 run_test 27Ca "check full striping across all OSTs"
2380
2381 test_27Cb() {
2382         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2383                 skip "server does not support overstriping"
2384         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2385                 skip_env "too many osts, skipping"
2386
2387         test_mkdir -p $DIR/$tdir
2388         local setcount=$(($OSTCOUNT * 2))
2389         [ $setcount -ge 160 ] || large_xattr_enabled ||
2390                 skip_env "ea_inode feature disabled"
2391
2392         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2393                 error "setstripe failed"
2394
2395         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2396         [ $count -eq $setcount ] ||
2397                 error "stripe count $count, should be $setcount"
2398
2399         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2400                 error "overstriped should be set in pattern"
2401
2402         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2403                 error "dd failed"
2404 }
2405 run_test 27Cb "more stripes than OSTs with -C"
2406
2407 test_27Cc() {
2408         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2409                 skip "server does not support overstriping"
2410         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2411
2412         test_mkdir -p $DIR/$tdir
2413         local setcount=$(($OSTCOUNT - 1))
2414
2415         [ $setcount -ge 160 ] || large_xattr_enabled ||
2416                 skip_env "ea_inode feature disabled"
2417
2418         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2419                 error "setstripe failed"
2420
2421         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2422         [ $count -eq $setcount ] ||
2423                 error "stripe count $count, should be $setcount"
2424
2425         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2426                 error "overstriped should not be set in pattern"
2427
2428         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2429                 error "dd failed"
2430 }
2431 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2432
2433 test_27Cd() {
2434         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2435                 skip "server does not support overstriping"
2436         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2437         large_xattr_enabled || skip_env "ea_inode feature disabled"
2438
2439         test_mkdir -p $DIR/$tdir
2440         local setcount=$LOV_MAX_STRIPE_COUNT
2441
2442         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2443                 error "setstripe failed"
2444
2445         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2446         [ $count -eq $setcount ] ||
2447                 error "stripe count $count, should be $setcount"
2448
2449         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2450                 error "overstriped should be set in pattern"
2451
2452         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2453                 error "dd failed"
2454
2455         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2456 }
2457 run_test 27Cd "test maximum stripe count"
2458
2459 test_27Ce() {
2460         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2461                 skip "server does not support overstriping"
2462         test_mkdir -p $DIR/$tdir
2463
2464         pool_add $TESTNAME || error "Pool creation failed"
2465         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2466
2467         local setcount=8
2468
2469         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2470                 error "setstripe failed"
2471
2472         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2473         [ $count -eq $setcount ] ||
2474                 error "stripe count $count, should be $setcount"
2475
2476         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2477                 error "overstriped should be set in pattern"
2478
2479         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2480                 error "dd failed"
2481
2482         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2483 }
2484 run_test 27Ce "test pool with overstriping"
2485
2486 test_27Cf() {
2487         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2488                 skip "server does not support overstriping"
2489         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2490                 skip_env "too many osts, skipping"
2491
2492         test_mkdir -p $DIR/$tdir
2493
2494         local setcount=$(($OSTCOUNT * 2))
2495         [ $setcount -ge 160 ] || large_xattr_enabled ||
2496                 skip_env "ea_inode feature disabled"
2497
2498         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2499                 error "setstripe failed"
2500
2501         echo 1 > $DIR/$tdir/$tfile
2502
2503         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2504         [ $count -eq $setcount ] ||
2505                 error "stripe count $count, should be $setcount"
2506
2507         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2508                 error "overstriped should be set in pattern"
2509
2510         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2511                 error "dd failed"
2512
2513         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2514 }
2515 run_test 27Cf "test default inheritance with overstriping"
2516
2517 test_27D() {
2518         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2519         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2520         remote_mds_nodsh && skip "remote MDS with nodsh"
2521
2522         local POOL=${POOL:-testpool}
2523         local first_ost=0
2524         local last_ost=$(($OSTCOUNT - 1))
2525         local ost_step=1
2526         local ost_list=$(seq $first_ost $ost_step $last_ost)
2527         local ost_range="$first_ost $last_ost $ost_step"
2528
2529         test_mkdir $DIR/$tdir
2530         pool_add $POOL || error "pool_add failed"
2531         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2532
2533         local skip27D
2534         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2535                 skip27D+="-s 29"
2536         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2537                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2538                         skip27D+=" -s 30,31"
2539         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2540           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2541                 skip27D+=" -s 32,33"
2542         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2543                 skip27D+=" -s 34"
2544         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2545                 error "llapi_layout_test failed"
2546
2547         destroy_test_pools || error "destroy test pools failed"
2548 }
2549 run_test 27D "validate llapi_layout API"
2550
2551 # Verify that default_easize is increased from its initial value after
2552 # accessing a widely striped file.
2553 test_27E() {
2554         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2555         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2556                 skip "client does not have LU-3338 fix"
2557
2558         # 72 bytes is the minimum space required to store striping
2559         # information for a file striped across one OST:
2560         # (sizeof(struct lov_user_md_v3) +
2561         #  sizeof(struct lov_user_ost_data_v1))
2562         local min_easize=72
2563         $LCTL set_param -n llite.*.default_easize $min_easize ||
2564                 error "lctl set_param failed"
2565         local easize=$($LCTL get_param -n llite.*.default_easize)
2566
2567         [ $easize -eq $min_easize ] ||
2568                 error "failed to set default_easize"
2569
2570         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2571                 error "setstripe failed"
2572         # In order to ensure stat() call actually talks to MDS we need to
2573         # do something drastic to this file to shake off all lock, e.g.
2574         # rename it (kills lookup lock forcing cache cleaning)
2575         mv $DIR/$tfile $DIR/${tfile}-1
2576         ls -l $DIR/${tfile}-1
2577         rm $DIR/${tfile}-1
2578
2579         easize=$($LCTL get_param -n llite.*.default_easize)
2580
2581         [ $easize -gt $min_easize ] ||
2582                 error "default_easize not updated"
2583 }
2584 run_test 27E "check that default extended attribute size properly increases"
2585
2586 test_27F() { # LU-5346/LU-7975
2587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2588         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2589         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2590                 skip "Need MDS version at least 2.8.51"
2591         remote_ost_nodsh && skip "remote OST with nodsh"
2592
2593         test_mkdir $DIR/$tdir
2594         rm -f $DIR/$tdir/f0
2595         $LFS setstripe -c 2 $DIR/$tdir
2596
2597         # stop all OSTs to reproduce situation for LU-7975 ticket
2598         for num in $(seq $OSTCOUNT); do
2599                 stop ost$num
2600         done
2601
2602         # open/create f0 with O_LOV_DELAY_CREATE
2603         # truncate f0 to a non-0 size
2604         # close
2605         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2606
2607         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2608         # open/write it again to force delayed layout creation
2609         cat /etc/hosts > $DIR/$tdir/f0 &
2610         catpid=$!
2611
2612         # restart OSTs
2613         for num in $(seq $OSTCOUNT); do
2614                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2615                         error "ost$num failed to start"
2616         done
2617
2618         wait $catpid || error "cat failed"
2619
2620         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2621         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2622                 error "wrong stripecount"
2623
2624 }
2625 run_test 27F "Client resend delayed layout creation with non-zero size"
2626
2627 test_27G() { #LU-10629
2628         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2629                 skip "Need MDS version at least 2.11.51"
2630         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2631         remote_mds_nodsh && skip "remote MDS with nodsh"
2632         local POOL=${POOL:-testpool}
2633         local ostrange="0 0 1"
2634
2635         test_mkdir $DIR/$tdir
2636         touch $DIR/$tdir/$tfile.nopool
2637         pool_add $POOL || error "pool_add failed"
2638         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2639         $LFS setstripe -p $POOL $DIR/$tdir
2640
2641         local pool=$($LFS getstripe -p $DIR/$tdir)
2642
2643         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2644         touch $DIR/$tdir/$tfile.default
2645         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2646         $LFS find $DIR/$tdir -type f --pool $POOL
2647         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2648         [[ "$found" == "2" ]] ||
2649                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2650
2651         $LFS setstripe -d $DIR/$tdir
2652
2653         pool=$($LFS getstripe -p -d $DIR/$tdir)
2654
2655         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2656 }
2657 run_test 27G "Clear OST pool from stripe"
2658
2659 test_27H() {
2660         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2661                 skip "Need MDS version newer than 2.11.54"
2662         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2663         test_mkdir $DIR/$tdir
2664         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2665         touch $DIR/$tdir/$tfile
2666         $LFS getstripe -c $DIR/$tdir/$tfile
2667         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2668                 error "two-stripe file doesn't have two stripes"
2669
2670         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2671         $LFS getstripe -y $DIR/$tdir/$tfile
2672         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2673              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2674                 error "expected l_ost_idx: [02]$ not matched"
2675
2676         # make sure ost list has been cleared
2677         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2678         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2679                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2680         touch $DIR/$tdir/f3
2681         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2682 }
2683 run_test 27H "Set specific OSTs stripe"
2684
2685 test_27I() {
2686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2687         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2688         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2689                 skip "Need MDS version newer than 2.12.52"
2690         local pool=$TESTNAME
2691         local ostrange="1 1 1"
2692
2693         save_layout_restore_at_exit $MOUNT
2694         $LFS setstripe -c 2 -i 0 $MOUNT
2695         pool_add $pool || error "pool_add failed"
2696         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2697         test_mkdir $DIR/$tdir
2698         $LFS setstripe -p $pool $DIR/$tdir
2699         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2700         $LFS getstripe $DIR/$tdir/$tfile
2701 }
2702 run_test 27I "check that root dir striping does not break parent dir one"
2703
2704 test_27J() {
2705         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2706                 skip "Need MDS version newer than 2.12.51"
2707
2708         test_mkdir $DIR/$tdir
2709         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2710         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2711
2712         # create foreign file (raw way)
2713         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2714                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2715
2716         # verify foreign file (raw way)
2717         parse_foreign_file -f $DIR/$tdir/$tfile |
2718                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2719                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2720         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2721                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2722         parse_foreign_file -f $DIR/$tdir/$tfile |
2723                 grep "lov_foreign_size: 73" ||
2724                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2725         parse_foreign_file -f $DIR/$tdir/$tfile |
2726                 grep "lov_foreign_type: 1" ||
2727                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2728         parse_foreign_file -f $DIR/$tdir/$tfile |
2729                 grep "lov_foreign_flags: 0x0000DA08" ||
2730                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2731         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2732                 grep "lov_foreign_value: 0x" |
2733                 sed -e 's/lov_foreign_value: 0x//')
2734         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2735         [[ $lov = ${lov2// /} ]] ||
2736                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2737
2738         # create foreign file (lfs + API)
2739         $LFS setstripe --foreign=daos --flags 0xda08 \
2740                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2741                 error "$DIR/$tdir/${tfile}2: create failed"
2742
2743         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2744                 grep "lfm_magic:.*0x0BD70BD0" ||
2745                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2746         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2747         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2748                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2749         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2750                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2751         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2752                 grep "lfm_flags:.*0x0000DA08" ||
2753                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2754         $LFS getstripe $DIR/$tdir/${tfile}2 |
2755                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2756                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2757
2758         # modify striping should fail
2759         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2760                 error "$DIR/$tdir/$tfile: setstripe should fail"
2761         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2762                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2763
2764         # R/W should fail
2765         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2766         cat $DIR/$tdir/${tfile}2 &&
2767                 error "$DIR/$tdir/${tfile}2: read should fail"
2768         cat /etc/passwd > $DIR/$tdir/$tfile &&
2769                 error "$DIR/$tdir/$tfile: write should fail"
2770         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2771                 error "$DIR/$tdir/${tfile}2: write should fail"
2772
2773         # chmod should work
2774         chmod 222 $DIR/$tdir/$tfile ||
2775                 error "$DIR/$tdir/$tfile: chmod failed"
2776         chmod 222 $DIR/$tdir/${tfile}2 ||
2777                 error "$DIR/$tdir/${tfile}2: chmod failed"
2778
2779         # chown should work
2780         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2781                 error "$DIR/$tdir/$tfile: chown failed"
2782         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2783                 error "$DIR/$tdir/${tfile}2: chown failed"
2784
2785         # rename should work
2786         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2787                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2788         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2789                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2790
2791         #remove foreign file
2792         rm $DIR/$tdir/${tfile}.new ||
2793                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2794         rm $DIR/$tdir/${tfile}2.new ||
2795                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2796 }
2797 run_test 27J "basic ops on file with foreign LOV"
2798
2799 test_27K() {
2800         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2801                 skip "Need MDS version newer than 2.12.49"
2802
2803         test_mkdir $DIR/$tdir
2804         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2805         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2806
2807         # create foreign dir (raw way)
2808         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2809                 error "create_foreign_dir FAILED"
2810
2811         # verify foreign dir (raw way)
2812         parse_foreign_dir -d $DIR/$tdir/$tdir |
2813                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2814                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2815         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2816                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2817         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2818                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2819         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2820                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2821         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2822                 grep "lmv_foreign_value: 0x" |
2823                 sed 's/lmv_foreign_value: 0x//')
2824         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2825                 sed 's/ //g')
2826         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2827
2828         # create foreign dir (lfs + API)
2829         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2830                 $DIR/$tdir/${tdir}2 ||
2831                 error "$DIR/$tdir/${tdir}2: create failed"
2832
2833         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2834                 grep "lfm_magic:.*0x0CD50CD0" ||
2835                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2836         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2837         # - sizeof(lfm_type) - sizeof(lfm_flags)
2838         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2839                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2840         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2841                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2842         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2843                 grep "lfm_flags:.*0x0000DA05" ||
2844                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2845         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2846                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2847                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2848
2849         # file create in dir should fail
2850         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2851         touch $DIR/$tdir/${tdir}2/$tfile &&
2852                 "$DIR/${tdir}2: file create should fail"
2853
2854         # chmod should work
2855         chmod 777 $DIR/$tdir/$tdir ||
2856                 error "$DIR/$tdir: chmod failed"
2857         chmod 777 $DIR/$tdir/${tdir}2 ||
2858                 error "$DIR/${tdir}2: chmod failed"
2859
2860         # chown should work
2861         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2862                 error "$DIR/$tdir: chown failed"
2863         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2864                 error "$DIR/${tdir}2: chown failed"
2865
2866         # rename should work
2867         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2868                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2869         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2870                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2871
2872         #remove foreign dir
2873         rmdir $DIR/$tdir/${tdir}.new ||
2874                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2875         rmdir $DIR/$tdir/${tdir}2.new ||
2876                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2877 }
2878 run_test 27K "basic ops on dir with foreign LMV"
2879
2880 test_27L() {
2881         remote_mds_nodsh && skip "remote MDS with nodsh"
2882
2883         local POOL=${POOL:-$TESTNAME}
2884
2885         pool_add $POOL || error "pool_add failed"
2886
2887         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2888                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2889                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2890 }
2891 run_test 27L "lfs pool_list gives correct pool name"
2892
2893 test_27M() {
2894         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2895                 skip "Need MDS version >= than 2.12.57"
2896         remote_mds_nodsh && skip "remote MDS with nodsh"
2897         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2898
2899         test_mkdir $DIR/$tdir
2900
2901         # Set default striping on directory
2902         $LFS setstripe -C 4 $DIR/$tdir
2903
2904         echo 1 > $DIR/$tdir/${tfile}.1
2905         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2906         local setcount=4
2907         [ $count -eq $setcount ] ||
2908                 error "(1) stripe count $count, should be $setcount"
2909
2910         # Capture existing append_stripe_count setting for restore
2911         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2912         local mdts=$(comma_list $(mdts_nodes))
2913         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2914
2915         local appendcount=$orig_count
2916         echo 1 >> $DIR/$tdir/${tfile}.2_append
2917         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2918         [ $count -eq $appendcount ] ||
2919                 error "(2)stripe count $count, should be $appendcount for append"
2920
2921         # Disable O_APPEND striping, verify it works
2922         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2923
2924         # Should now get the default striping, which is 4
2925         setcount=4
2926         echo 1 >> $DIR/$tdir/${tfile}.3_append
2927         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2928         [ $count -eq $setcount ] ||
2929                 error "(3) stripe count $count, should be $setcount"
2930
2931         # Try changing the stripe count for append files
2932         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2933
2934         # Append striping is now 2 (directory default is still 4)
2935         appendcount=2
2936         echo 1 >> $DIR/$tdir/${tfile}.4_append
2937         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2938         [ $count -eq $appendcount ] ||
2939                 error "(4) stripe count $count, should be $appendcount for append"
2940
2941         # Test append stripe count of -1
2942         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2943         appendcount=$OSTCOUNT
2944         echo 1 >> $DIR/$tdir/${tfile}.5
2945         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2946         [ $count -eq $appendcount ] ||
2947                 error "(5) stripe count $count, should be $appendcount for append"
2948
2949         # Set append striping back to default of 1
2950         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2951
2952         # Try a new default striping, PFL + DOM
2953         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2954
2955         # Create normal DOM file, DOM returns stripe count == 0
2956         setcount=0
2957         touch $DIR/$tdir/${tfile}.6
2958         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2959         [ $count -eq $setcount ] ||
2960                 error "(6) stripe count $count, should be $setcount"
2961
2962         # Show
2963         appendcount=1
2964         echo 1 >> $DIR/$tdir/${tfile}.7_append
2965         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2966         [ $count -eq $appendcount ] ||
2967                 error "(7) stripe count $count, should be $appendcount for append"
2968
2969         # Clean up DOM layout
2970         $LFS setstripe -d $DIR/$tdir
2971
2972         # Now test that append striping works when layout is from root
2973         $LFS setstripe -c 2 $MOUNT
2974         # Make a special directory for this
2975         mkdir $DIR/${tdir}/${tdir}.2
2976         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2977
2978         # Verify for normal file
2979         setcount=2
2980         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2981         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2982         [ $count -eq $setcount ] ||
2983                 error "(8) stripe count $count, should be $setcount"
2984
2985         appendcount=1
2986         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2987         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2988         [ $count -eq $appendcount ] ||
2989                 error "(9) stripe count $count, should be $appendcount for append"
2990
2991         # Now test O_APPEND striping with pools
2992         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2993         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2994
2995         # Create the pool
2996         pool_add $TESTNAME || error "pool creation failed"
2997         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2998
2999         echo 1 >> $DIR/$tdir/${tfile}.10_append
3000
3001         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3002         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3003
3004         # Check that count is still correct
3005         appendcount=1
3006         echo 1 >> $DIR/$tdir/${tfile}.11_append
3007         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3008         [ $count -eq $appendcount ] ||
3009                 error "(11) stripe count $count, should be $appendcount for append"
3010
3011         # Disable O_APPEND stripe count, verify pool works separately
3012         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3013
3014         echo 1 >> $DIR/$tdir/${tfile}.12_append
3015
3016         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3017         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3018
3019         # Remove pool setting, verify it's not applied
3020         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3021
3022         echo 1 >> $DIR/$tdir/${tfile}.13_append
3023
3024         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3025         [ "$pool" = "" ] || error "(13) pool found: $pool"
3026 }
3027 run_test 27M "test O_APPEND striping"
3028
3029 test_27N() {
3030         combined_mgs_mds && skip "needs separate MGS/MDT"
3031
3032         pool_add $TESTNAME || error "pool_add failed"
3033         do_facet mgs "$LCTL pool_list $FSNAME" |
3034                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3035                 error "lctl pool_list on MGS failed"
3036 }
3037 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3038
3039 # createtest also checks that device nodes are created and
3040 # then visible correctly (#2091)
3041 test_28() { # bug 2091
3042         test_mkdir $DIR/d28
3043         $CREATETEST $DIR/d28/ct || error "createtest failed"
3044 }
3045 run_test 28 "create/mknod/mkdir with bad file types ============"
3046
3047 test_29() {
3048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3049
3050         sync; sleep 1; sync # flush out any dirty pages from previous tests
3051         cancel_lru_locks
3052         test_mkdir $DIR/d29
3053         touch $DIR/d29/foo
3054         log 'first d29'
3055         ls -l $DIR/d29
3056
3057         declare -i LOCKCOUNTORIG=0
3058         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3059                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3060         done
3061         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3062
3063         declare -i LOCKUNUSEDCOUNTORIG=0
3064         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3065                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3066         done
3067
3068         log 'second d29'
3069         ls -l $DIR/d29
3070         log 'done'
3071
3072         declare -i LOCKCOUNTCURRENT=0
3073         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3074                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3075         done
3076
3077         declare -i LOCKUNUSEDCOUNTCURRENT=0
3078         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3079                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3080         done
3081
3082         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3083                 $LCTL set_param -n ldlm.dump_namespaces ""
3084                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3085                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3086                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3087                 return 2
3088         fi
3089         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3090                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3091                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3092                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3093                 return 3
3094         fi
3095 }
3096 run_test 29 "IT_GETATTR regression  ============================"
3097
3098 test_30a() { # was test_30
3099         cp $(which ls) $DIR || cp /bin/ls $DIR
3100         $DIR/ls / || error "Can't execute binary from lustre"
3101         rm $DIR/ls
3102 }
3103 run_test 30a "execute binary from Lustre (execve) =============="
3104
3105 test_30b() {
3106         cp `which ls` $DIR || cp /bin/ls $DIR
3107         chmod go+rx $DIR/ls
3108         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3109         rm $DIR/ls
3110 }
3111 run_test 30b "execute binary from Lustre as non-root ==========="
3112
3113 test_30c() { # b=22376
3114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3115
3116         cp $(which ls) $DIR || cp /bin/ls $DIR
3117         chmod a-rw $DIR/ls
3118         cancel_lru_locks mdc
3119         cancel_lru_locks osc
3120         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3121         rm -f $DIR/ls
3122 }
3123 run_test 30c "execute binary from Lustre without read perms ===="
3124
3125 test_30d() {
3126         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3127
3128         for i in {1..10}; do
3129                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3130                 local PID=$!
3131                 sleep 1
3132                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3133                 wait $PID || error "executing dd from Lustre failed"
3134                 rm -f $DIR/$tfile
3135         done
3136
3137         rm -f $DIR/dd
3138 }
3139 run_test 30d "execute binary from Lustre while clear locks"
3140
3141 test_31a() {
3142         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3143         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3144 }
3145 run_test 31a "open-unlink file =================================="
3146
3147 test_31b() {
3148         touch $DIR/f31 || error "touch $DIR/f31 failed"
3149         ln $DIR/f31 $DIR/f31b || error "ln failed"
3150         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3151         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3152 }
3153 run_test 31b "unlink file with multiple links while open ======="
3154
3155 test_31c() {
3156         touch $DIR/f31 || error "touch $DIR/f31 failed"
3157         ln $DIR/f31 $DIR/f31c || error "ln failed"
3158         multiop_bg_pause $DIR/f31 O_uc ||
3159                 error "multiop_bg_pause for $DIR/f31 failed"
3160         MULTIPID=$!
3161         $MULTIOP $DIR/f31c Ouc
3162         kill -USR1 $MULTIPID
3163         wait $MULTIPID
3164 }
3165 run_test 31c "open-unlink file with multiple links ============="
3166
3167 test_31d() {
3168         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3169         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3170 }
3171 run_test 31d "remove of open directory ========================="
3172
3173 test_31e() { # bug 2904
3174         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3175 }
3176 run_test 31e "remove of open non-empty directory ==============="
3177
3178 test_31f() { # bug 4554
3179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3180
3181         set -vx
3182         test_mkdir $DIR/d31f
3183         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3184         cp /etc/hosts $DIR/d31f
3185         ls -l $DIR/d31f
3186         $LFS getstripe $DIR/d31f/hosts
3187         multiop_bg_pause $DIR/d31f D_c || return 1
3188         MULTIPID=$!
3189
3190         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3191         test_mkdir $DIR/d31f
3192         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3193         cp /etc/hosts $DIR/d31f
3194         ls -l $DIR/d31f
3195         $LFS getstripe $DIR/d31f/hosts
3196         multiop_bg_pause $DIR/d31f D_c || return 1
3197         MULTIPID2=$!
3198
3199         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3200         wait $MULTIPID || error "first opendir $MULTIPID failed"
3201
3202         sleep 6
3203
3204         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3205         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3206         set +vx
3207 }
3208 run_test 31f "remove of open directory with open-unlink file ==="
3209
3210 test_31g() {
3211         echo "-- cross directory link --"
3212         test_mkdir -c1 $DIR/${tdir}ga
3213         test_mkdir -c1 $DIR/${tdir}gb
3214         touch $DIR/${tdir}ga/f
3215         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3216         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3217         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3218         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3219         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3220 }
3221 run_test 31g "cross directory link==============="
3222
3223 test_31h() {
3224         echo "-- cross directory link --"
3225         test_mkdir -c1 $DIR/${tdir}
3226         test_mkdir -c1 $DIR/${tdir}/dir
3227         touch $DIR/${tdir}/f
3228         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3229         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3230         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3231         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3232         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3233 }
3234 run_test 31h "cross directory link under child==============="
3235
3236 test_31i() {
3237         echo "-- cross directory link --"
3238         test_mkdir -c1 $DIR/$tdir
3239         test_mkdir -c1 $DIR/$tdir/dir
3240         touch $DIR/$tdir/dir/f
3241         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3242         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3243         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3244         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3245         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3246 }
3247 run_test 31i "cross directory link under parent==============="
3248
3249 test_31j() {
3250         test_mkdir -c1 -p $DIR/$tdir
3251         test_mkdir -c1 -p $DIR/$tdir/dir1
3252         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3253         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3254         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3255         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3256         return 0
3257 }
3258 run_test 31j "link for directory==============="
3259
3260 test_31k() {
3261         test_mkdir -c1 -p $DIR/$tdir
3262         touch $DIR/$tdir/s
3263         touch $DIR/$tdir/exist
3264         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3265         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3266         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3267         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3268         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3269         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3270         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3271         return 0
3272 }
3273 run_test 31k "link to file: the same, non-existing, dir==============="
3274
3275 test_31m() {
3276         mkdir $DIR/d31m
3277         touch $DIR/d31m/s
3278         mkdir $DIR/d31m2
3279         touch $DIR/d31m2/exist
3280         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3281         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3282         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3283         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3284         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3285         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3286         return 0
3287 }
3288 run_test 31m "link to file: the same, non-existing, dir==============="
3289
3290 test_31n() {
3291         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3292         nlink=$(stat --format=%h $DIR/$tfile)
3293         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3294         local fd=$(free_fd)
3295         local cmd="exec $fd<$DIR/$tfile"
3296         eval $cmd
3297         cmd="exec $fd<&-"
3298         trap "eval $cmd" EXIT
3299         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3300         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3301         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3302         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3303         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3304         eval $cmd
3305 }
3306 run_test 31n "check link count of unlinked file"
3307
3308 link_one() {
3309         local tempfile=$(mktemp $1_XXXXXX)
3310         mlink $tempfile $1 2> /dev/null &&
3311                 echo "$BASHPID: link $tempfile to $1 succeeded"
3312         munlink $tempfile
3313 }
3314
3315 test_31o() { # LU-2901
3316         test_mkdir $DIR/$tdir
3317         for LOOP in $(seq 100); do
3318                 rm -f $DIR/$tdir/$tfile*
3319                 for THREAD in $(seq 8); do
3320                         link_one $DIR/$tdir/$tfile.$LOOP &
3321                 done
3322                 wait
3323                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3324                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3325                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3326                         break || true
3327         done
3328 }
3329 run_test 31o "duplicate hard links with same filename"
3330
3331 test_31p() {
3332         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3333
3334         test_mkdir $DIR/$tdir
3335         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3336         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3337
3338         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3339                 error "open unlink test1 failed"
3340         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3341                 error "open unlink test2 failed"
3342
3343         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3344                 error "test1 still exists"
3345         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3346                 error "test2 still exists"
3347 }
3348 run_test 31p "remove of open striped directory"
3349
3350 cleanup_test32_mount() {
3351         local rc=0
3352         trap 0
3353         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3354         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3355         losetup -d $loopdev || true
3356         rm -rf $DIR/$tdir
3357         return $rc
3358 }
3359
3360 test_32a() {
3361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3362
3363         echo "== more mountpoints and symlinks ================="
3364         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3365         trap cleanup_test32_mount EXIT
3366         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3367         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3368                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3369         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3370                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3371         cleanup_test32_mount
3372 }
3373 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3374
3375 test_32b() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3379         trap cleanup_test32_mount EXIT
3380         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3381         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3382                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3383         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3384                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3385         cleanup_test32_mount
3386 }
3387 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3388
3389 test_32c() {
3390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3391
3392         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3393         trap cleanup_test32_mount EXIT
3394         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3395         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3396                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3397         test_mkdir -p $DIR/$tdir/d2/test_dir
3398         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3399                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3400         cleanup_test32_mount
3401 }
3402 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3403
3404 test_32d() {
3405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3406
3407         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3408         trap cleanup_test32_mount EXIT
3409         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3410         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3411                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3412         test_mkdir -p $DIR/$tdir/d2/test_dir
3413         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3414                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3415         cleanup_test32_mount
3416 }
3417 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3418
3419 test_32e() {
3420         rm -fr $DIR/$tdir
3421         test_mkdir -p $DIR/$tdir/tmp
3422         local tmp_dir=$DIR/$tdir/tmp
3423         ln -s $DIR/$tdir $tmp_dir/symlink11
3424         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3425         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3426         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3427 }
3428 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3429
3430 test_32f() {
3431         rm -fr $DIR/$tdir
3432         test_mkdir -p $DIR/$tdir/tmp
3433         local tmp_dir=$DIR/$tdir/tmp
3434         ln -s $DIR/$tdir $tmp_dir/symlink11
3435         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3436         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3437         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3438 }
3439 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3440
3441 test_32g() {
3442         local tmp_dir=$DIR/$tdir/tmp
3443         test_mkdir -p $tmp_dir
3444         test_mkdir $DIR/${tdir}2
3445         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3446         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3447         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3448         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3449         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3450         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3451 }
3452 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3453
3454 test_32h() {
3455         rm -fr $DIR/$tdir $DIR/${tdir}2
3456         tmp_dir=$DIR/$tdir/tmp
3457         test_mkdir -p $tmp_dir
3458         test_mkdir $DIR/${tdir}2
3459         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3460         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3461         ls $tmp_dir/symlink12 || error "listing symlink12"
3462         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3463 }
3464 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3465
3466 test_32i() {
3467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3468
3469         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3470         trap cleanup_test32_mount EXIT
3471         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3472         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3473                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3474         touch $DIR/$tdir/test_file
3475         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3476                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3477         cleanup_test32_mount
3478 }
3479 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3480
3481 test_32j() {
3482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3483
3484         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3485         trap cleanup_test32_mount EXIT
3486         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3487         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3488                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3489         touch $DIR/$tdir/test_file
3490         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3491                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3492         cleanup_test32_mount
3493 }
3494 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3495
3496 test_32k() {
3497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3498
3499         rm -fr $DIR/$tdir
3500         trap cleanup_test32_mount EXIT
3501         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3502         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3503                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3504         test_mkdir -p $DIR/$tdir/d2
3505         touch $DIR/$tdir/d2/test_file || error "touch failed"
3506         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3507                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3508         cleanup_test32_mount
3509 }
3510 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3511
3512 test_32l() {
3513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3514
3515         rm -fr $DIR/$tdir
3516         trap cleanup_test32_mount EXIT
3517         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3518         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3519                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3520         test_mkdir -p $DIR/$tdir/d2
3521         touch $DIR/$tdir/d2/test_file || error "touch failed"
3522         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3523                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3524         cleanup_test32_mount
3525 }
3526 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3527
3528 test_32m() {
3529         rm -fr $DIR/d32m
3530         test_mkdir -p $DIR/d32m/tmp
3531         TMP_DIR=$DIR/d32m/tmp
3532         ln -s $DIR $TMP_DIR/symlink11
3533         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3534         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3535                 error "symlink11 not a link"
3536         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3537                 error "symlink01 not a link"
3538 }
3539 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3540
3541 test_32n() {
3542         rm -fr $DIR/d32n
3543         test_mkdir -p $DIR/d32n/tmp
3544         TMP_DIR=$DIR/d32n/tmp
3545         ln -s $DIR $TMP_DIR/symlink11
3546         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3547         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3548         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3549 }
3550 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3551
3552 test_32o() {
3553         touch $DIR/$tfile
3554         test_mkdir -p $DIR/d32o/tmp
3555         TMP_DIR=$DIR/d32o/tmp
3556         ln -s $DIR/$tfile $TMP_DIR/symlink12
3557         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3558         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3559                 error "symlink12 not a link"
3560         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3561         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3562                 error "$DIR/d32o/tmp/symlink12 not file type"
3563         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3564                 error "$DIR/d32o/symlink02 not file type"
3565 }
3566 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3567
3568 test_32p() {
3569         log 32p_1
3570         rm -fr $DIR/d32p
3571         log 32p_2
3572         rm -f $DIR/$tfile
3573         log 32p_3
3574         touch $DIR/$tfile
3575         log 32p_4
3576         test_mkdir -p $DIR/d32p/tmp
3577         log 32p_5
3578         TMP_DIR=$DIR/d32p/tmp
3579         log 32p_6
3580         ln -s $DIR/$tfile $TMP_DIR/symlink12
3581         log 32p_7
3582         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3583         log 32p_8
3584         cat $DIR/d32p/tmp/symlink12 ||
3585                 error "Can't open $DIR/d32p/tmp/symlink12"
3586         log 32p_9
3587         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3588         log 32p_10
3589 }
3590 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3591
3592 test_32q() {
3593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3594
3595         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3596         trap cleanup_test32_mount EXIT
3597         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3598         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3599         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3600                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3601         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3602         cleanup_test32_mount
3603 }
3604 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3605
3606 test_32r() {
3607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3608
3609         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3610         trap cleanup_test32_mount EXIT
3611         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3612         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3613         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3614                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3615         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3616         cleanup_test32_mount
3617 }
3618 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3619
3620 test_33aa() {
3621         rm -f $DIR/$tfile
3622         touch $DIR/$tfile
3623         chmod 444 $DIR/$tfile
3624         chown $RUNAS_ID $DIR/$tfile
3625         log 33_1
3626         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3627         log 33_2
3628 }
3629 run_test 33aa "write file with mode 444 (should return error)"
3630
3631 test_33a() {
3632         rm -fr $DIR/$tdir
3633         test_mkdir $DIR/$tdir
3634         chown $RUNAS_ID $DIR/$tdir
3635         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3636                 error "$RUNAS create $tdir/$tfile failed"
3637         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3638                 error "open RDWR" || true
3639 }
3640 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3641
3642 test_33b() {
3643         rm -fr $DIR/$tdir
3644         test_mkdir $DIR/$tdir
3645         chown $RUNAS_ID $DIR/$tdir
3646         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3647 }
3648 run_test 33b "test open file with malformed flags (No panic)"
3649
3650 test_33c() {
3651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3652         remote_ost_nodsh && skip "remote OST with nodsh"
3653
3654         local ostnum
3655         local ostname
3656         local write_bytes
3657         local all_zeros
3658
3659         all_zeros=:
3660         rm -fr $DIR/$tdir
3661         test_mkdir $DIR/$tdir
3662         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3663
3664         sync
3665         for ostnum in $(seq $OSTCOUNT); do
3666                 # test-framework's OST numbering is one-based, while Lustre's
3667                 # is zero-based
3668                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3669                 # Parsing llobdstat's output sucks; we could grep the /proc
3670                 # path, but that's likely to not be as portable as using the
3671                 # llobdstat utility.  So we parse lctl output instead.
3672                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3673                         obdfilter/$ostname/stats |
3674                         awk '/^write_bytes/ {print $7}' )
3675                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3676                 if (( ${write_bytes:-0} > 0 ))
3677                 then
3678                         all_zeros=false
3679                         break;
3680                 fi
3681         done
3682
3683         $all_zeros || return 0
3684
3685         # Write four bytes
3686         echo foo > $DIR/$tdir/bar
3687         # Really write them
3688         sync
3689
3690         # Total up write_bytes after writing.  We'd better find non-zeros.
3691         for ostnum in $(seq $OSTCOUNT); do
3692                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3693                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3694                         obdfilter/$ostname/stats |
3695                         awk '/^write_bytes/ {print $7}' )
3696                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3697                 if (( ${write_bytes:-0} > 0 ))
3698                 then
3699                         all_zeros=false
3700                         break;
3701                 fi
3702         done
3703
3704         if $all_zeros
3705         then
3706                 for ostnum in $(seq $OSTCOUNT); do
3707                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3708                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3709                         do_facet ost$ostnum lctl get_param -n \
3710                                 obdfilter/$ostname/stats
3711                 done
3712                 error "OST not keeping write_bytes stats (b22312)"
3713         fi
3714 }
3715 run_test 33c "test llobdstat and write_bytes"
3716
3717 test_33d() {
3718         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3720
3721         local MDTIDX=1
3722         local remote_dir=$DIR/$tdir/remote_dir
3723
3724         test_mkdir $DIR/$tdir
3725         $LFS mkdir -i $MDTIDX $remote_dir ||
3726                 error "create remote directory failed"
3727
3728         touch $remote_dir/$tfile
3729         chmod 444 $remote_dir/$tfile
3730         chown $RUNAS_ID $remote_dir/$tfile
3731
3732         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3733
3734         chown $RUNAS_ID $remote_dir
3735         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3736                                         error "create" || true
3737         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3738                                     error "open RDWR" || true
3739         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3740 }
3741 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3742
3743 test_33e() {
3744         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3745
3746         mkdir $DIR/$tdir
3747
3748         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3749         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3750         mkdir $DIR/$tdir/local_dir
3751
3752         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3753         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3754         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3755
3756         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3757                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3758
3759         rmdir $DIR/$tdir/* || error "rmdir failed"
3760
3761         umask 777
3762         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3763         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3764         mkdir $DIR/$tdir/local_dir
3765
3766         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3767         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3768         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3769
3770         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3771                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3772
3773         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3774
3775         umask 000
3776         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3777         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3778         mkdir $DIR/$tdir/local_dir
3779
3780         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3781         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3782         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3783
3784         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3785                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3786 }
3787 run_test 33e "mkdir and striped directory should have same mode"
3788
3789 cleanup_33f() {
3790         trap 0
3791         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3792 }
3793
3794 test_33f() {
3795         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3796         remote_mds_nodsh && skip "remote MDS with nodsh"
3797
3798         mkdir $DIR/$tdir
3799         chmod go+rwx $DIR/$tdir
3800         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3801         trap cleanup_33f EXIT
3802
3803         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3804                 error "cannot create striped directory"
3805
3806         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3807                 error "cannot create files in striped directory"
3808
3809         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3810                 error "cannot remove files in striped directory"
3811
3812         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3813                 error "cannot remove striped directory"
3814
3815         cleanup_33f
3816 }
3817 run_test 33f "nonroot user can create, access, and remove a striped directory"
3818
3819 test_33g() {
3820         mkdir -p $DIR/$tdir/dir2
3821
3822         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3823         echo $err
3824         [[ $err =~ "exists" ]] || error "Not exists error"
3825 }
3826 run_test 33g "nonroot user create already existing root created file"
3827
3828 test_33h() {
3829         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3830         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3831                 skip "Need MDS version at least 2.13.50"
3832
3833         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3834                 error "mkdir $tdir failed"
3835         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3836
3837         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3838         local index2
3839
3840         for fname in $DIR/$tdir/$tfile.bak \
3841                      $DIR/$tdir/$tfile.SAV \
3842                      $DIR/$tdir/$tfile.orig \
3843                      $DIR/$tdir/$tfile~; do
3844                 touch $fname  || error "touch $fname failed"
3845                 index2=$($LFS getstripe -m $fname)
3846                 [ $index -eq $index2 ] ||
3847                         error "$fname MDT index mismatch $index != $index2"
3848         done
3849
3850         local failed=0
3851         for i in {1..250}; do
3852                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3853                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3854                         touch $fname  || error "touch $fname failed"
3855                         index2=$($LFS getstripe -m $fname)
3856                         if [[ $index != $index2 ]]; then
3857                                 failed=$((failed + 1))
3858                                 echo "$fname MDT index mismatch $index != $index2"
3859                         fi
3860                 done
3861         done
3862         echo "$failed MDT index mismatches"
3863         (( failed < 20 )) || error "MDT index mismatch $failed times"
3864
3865 }
3866 run_test 33h "temp file is located on the same MDT as target"
3867
3868 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3869 test_34a() {
3870         rm -f $DIR/f34
3871         $MCREATE $DIR/f34 || error "mcreate failed"
3872         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3873                 error "getstripe failed"
3874         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3875         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3876                 error "getstripe failed"
3877         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3878                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3879 }
3880 run_test 34a "truncate file that has not been opened ==========="
3881
3882 test_34b() {
3883         [ ! -f $DIR/f34 ] && test_34a
3884         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3885                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3886         $OPENFILE -f O_RDONLY $DIR/f34
3887         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3888                 error "getstripe failed"
3889         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3890                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3891 }
3892 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3893
3894 test_34c() {
3895         [ ! -f $DIR/f34 ] && test_34a
3896         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3897                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3898         $OPENFILE -f O_RDWR $DIR/f34
3899         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3900                 error "$LFS getstripe failed"
3901         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3902                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3903 }
3904 run_test 34c "O_RDWR opening file-with-size works =============="
3905
3906 test_34d() {
3907         [ ! -f $DIR/f34 ] && test_34a
3908         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3909                 error "dd failed"
3910         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3911                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3912         rm $DIR/f34
3913 }
3914 run_test 34d "write to sparse file ============================="
3915
3916 test_34e() {
3917         rm -f $DIR/f34e
3918         $MCREATE $DIR/f34e || error "mcreate failed"
3919         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3920         $CHECKSTAT -s 1000 $DIR/f34e ||
3921                 error "Size of $DIR/f34e not equal to 1000 bytes"
3922         $OPENFILE -f O_RDWR $DIR/f34e
3923         $CHECKSTAT -s 1000 $DIR/f34e ||
3924                 error "Size of $DIR/f34e not equal to 1000 bytes"
3925 }
3926 run_test 34e "create objects, some with size and some without =="
3927
3928 test_34f() { # bug 6242, 6243
3929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3930
3931         SIZE34F=48000
3932         rm -f $DIR/f34f
3933         $MCREATE $DIR/f34f || error "mcreate failed"
3934         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3935         dd if=$DIR/f34f of=$TMP/f34f
3936         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3937         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3938         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3939         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3940         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3941 }
3942 run_test 34f "read from a file with no objects until EOF ======="
3943
3944 test_34g() {
3945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3946
3947         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3948                 error "dd failed"
3949         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3950         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3951                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3952         cancel_lru_locks osc
3953         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3954                 error "wrong size after lock cancel"
3955
3956         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3957         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3958                 error "expanding truncate failed"
3959         cancel_lru_locks osc
3960         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3961                 error "wrong expanded size after lock cancel"
3962 }
3963 run_test 34g "truncate long file ==============================="
3964
3965 test_34h() {
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967
3968         local gid=10
3969         local sz=1000
3970
3971         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3972         sync # Flush the cache so that multiop below does not block on cache
3973              # flush when getting the group lock
3974         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3975         MULTIPID=$!
3976
3977         # Since just timed wait is not good enough, let's do a sync write
3978         # that way we are sure enough time for a roundtrip + processing
3979         # passed + 2 seconds of extra margin.
3980         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3981         rm $DIR/${tfile}-1
3982         sleep 2
3983
3984         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3985                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3986                 kill -9 $MULTIPID
3987         fi
3988         wait $MULTIPID
3989         local nsz=`stat -c %s $DIR/$tfile`
3990         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3991 }
3992 run_test 34h "ftruncate file under grouplock should not block"
3993
3994 test_35a() {
3995         cp /bin/sh $DIR/f35a
3996         chmod 444 $DIR/f35a
3997         chown $RUNAS_ID $DIR/f35a
3998         $RUNAS $DIR/f35a && error || true
3999         rm $DIR/f35a
4000 }
4001 run_test 35a "exec file with mode 444 (should return and not leak)"
4002
4003 test_36a() {
4004         rm -f $DIR/f36
4005         utime $DIR/f36 || error "utime failed for MDS"
4006 }
4007 run_test 36a "MDS utime check (mknod, utime)"
4008
4009 test_36b() {
4010         echo "" > $DIR/f36
4011         utime $DIR/f36 || error "utime failed for OST"
4012 }
4013 run_test 36b "OST utime check (open, utime)"
4014
4015 test_36c() {
4016         rm -f $DIR/d36/f36
4017         test_mkdir $DIR/d36
4018         chown $RUNAS_ID $DIR/d36
4019         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4020 }
4021 run_test 36c "non-root MDS utime check (mknod, utime)"
4022
4023 test_36d() {
4024         [ ! -d $DIR/d36 ] && test_36c
4025         echo "" > $DIR/d36/f36
4026         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4027 }
4028 run_test 36d "non-root OST utime check (open, utime)"
4029
4030 test_36e() {
4031         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4032
4033         test_mkdir $DIR/$tdir
4034         touch $DIR/$tdir/$tfile
4035         $RUNAS utime $DIR/$tdir/$tfile &&
4036                 error "utime worked, expected failure" || true
4037 }
4038 run_test 36e "utime on non-owned file (should return error)"
4039
4040 subr_36fh() {
4041         local fl="$1"
4042         local LANG_SAVE=$LANG
4043         local LC_LANG_SAVE=$LC_LANG
4044         export LANG=C LC_LANG=C # for date language
4045
4046         DATESTR="Dec 20  2000"
4047         test_mkdir $DIR/$tdir
4048         lctl set_param fail_loc=$fl
4049         date; date +%s
4050         cp /etc/hosts $DIR/$tdir/$tfile
4051         sync & # write RPC generated with "current" inode timestamp, but delayed
4052         sleep 1
4053         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4054         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4055         cancel_lru_locks $OSC
4056         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4057         date; date +%s
4058         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4059                 echo "BEFORE: $LS_BEFORE" && \
4060                 echo "AFTER : $LS_AFTER" && \
4061                 echo "WANT  : $DATESTR" && \
4062                 error "$DIR/$tdir/$tfile timestamps changed" || true
4063
4064         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4065 }
4066
4067 test_36f() {
4068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4069
4070         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4071         subr_36fh "0x80000214"
4072 }
4073 run_test 36f "utime on file racing with OST BRW write =========="
4074
4075 test_36g() {
4076         remote_ost_nodsh && skip "remote OST with nodsh"
4077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4078         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4079                 skip "Need MDS version at least 2.12.51"
4080
4081         local fmd_max_age
4082         local fmd
4083         local facet="ost1"
4084         local tgt="obdfilter"
4085
4086         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4087
4088         test_mkdir $DIR/$tdir
4089         fmd_max_age=$(do_facet $facet \
4090                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4091                 head -n 1")
4092
4093         echo "FMD max age: ${fmd_max_age}s"
4094         touch $DIR/$tdir/$tfile
4095         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4096                 gawk '{cnt=cnt+$1}  END{print cnt}')
4097         echo "FMD before: $fmd"
4098         [[ $fmd == 0 ]] &&
4099                 error "FMD wasn't create by touch"
4100         sleep $((fmd_max_age + 12))
4101         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4102                 gawk '{cnt=cnt+$1}  END{print cnt}')
4103         echo "FMD after: $fmd"
4104         [[ $fmd == 0 ]] ||
4105                 error "FMD wasn't expired by ping"
4106 }
4107 run_test 36g "FMD cache expiry ====================="
4108
4109 test_36h() {
4110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4111
4112         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4113         subr_36fh "0x80000227"
4114 }
4115 run_test 36h "utime on file racing with OST BRW write =========="
4116
4117 test_36i() {
4118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4119
4120         test_mkdir $DIR/$tdir
4121         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4122
4123         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4124         local new_mtime=$((mtime + 200))
4125
4126         #change Modify time of striped dir
4127         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4128                         error "change mtime failed"
4129
4130         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4131
4132         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4133 }
4134 run_test 36i "change mtime on striped directory"
4135
4136 # test_37 - duplicate with tests 32q 32r
4137
4138 test_38() {
4139         local file=$DIR/$tfile
4140         touch $file
4141         openfile -f O_DIRECTORY $file
4142         local RC=$?
4143         local ENOTDIR=20
4144         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4145         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4146 }
4147 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4148
4149 test_39a() { # was test_39
4150         touch $DIR/$tfile
4151         touch $DIR/${tfile}2
4152 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4153 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4154 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4155         sleep 2
4156         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4157         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4158                 echo "mtime"
4159                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4160                 echo "atime"
4161                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4162                 echo "ctime"
4163                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4164                 error "O_TRUNC didn't change timestamps"
4165         fi
4166 }
4167 run_test 39a "mtime changed on create"
4168
4169 test_39b() {
4170         test_mkdir -c1 $DIR/$tdir
4171         cp -p /etc/passwd $DIR/$tdir/fopen
4172         cp -p /etc/passwd $DIR/$tdir/flink
4173         cp -p /etc/passwd $DIR/$tdir/funlink
4174         cp -p /etc/passwd $DIR/$tdir/frename
4175         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4176
4177         sleep 1
4178         echo "aaaaaa" >> $DIR/$tdir/fopen
4179         echo "aaaaaa" >> $DIR/$tdir/flink
4180         echo "aaaaaa" >> $DIR/$tdir/funlink
4181         echo "aaaaaa" >> $DIR/$tdir/frename
4182
4183         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4184         local link_new=`stat -c %Y $DIR/$tdir/flink`
4185         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4186         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4187
4188         cat $DIR/$tdir/fopen > /dev/null
4189         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4190         rm -f $DIR/$tdir/funlink2
4191         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4192
4193         for (( i=0; i < 2; i++ )) ; do
4194                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4195                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4196                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4197                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4198
4199                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4200                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4201                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4202                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4203
4204                 cancel_lru_locks $OSC
4205                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4206         done
4207 }
4208 run_test 39b "mtime change on open, link, unlink, rename  ======"
4209
4210 # this should be set to past
4211 TEST_39_MTIME=`date -d "1 year ago" +%s`
4212
4213 # bug 11063
4214 test_39c() {
4215         touch $DIR1/$tfile
4216         sleep 2
4217         local mtime0=`stat -c %Y $DIR1/$tfile`
4218
4219         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4220         local mtime1=`stat -c %Y $DIR1/$tfile`
4221         [ "$mtime1" = $TEST_39_MTIME ] || \
4222                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4223
4224         local d1=`date +%s`
4225         echo hello >> $DIR1/$tfile
4226         local d2=`date +%s`
4227         local mtime2=`stat -c %Y $DIR1/$tfile`
4228         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4229                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4230
4231         mv $DIR1/$tfile $DIR1/$tfile-1
4232
4233         for (( i=0; i < 2; i++ )) ; do
4234                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4235                 [ "$mtime2" = "$mtime3" ] || \
4236                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4237
4238                 cancel_lru_locks $OSC
4239                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4240         done
4241 }
4242 run_test 39c "mtime change on rename ==========================="
4243
4244 # bug 21114
4245 test_39d() {
4246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4247
4248         touch $DIR1/$tfile
4249         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4250
4251         for (( i=0; i < 2; i++ )) ; do
4252                 local mtime=`stat -c %Y $DIR1/$tfile`
4253                 [ $mtime = $TEST_39_MTIME ] || \
4254                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4255
4256                 cancel_lru_locks $OSC
4257                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4258         done
4259 }
4260 run_test 39d "create, utime, stat =============================="
4261
4262 # bug 21114
4263 test_39e() {
4264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4265
4266         touch $DIR1/$tfile
4267         local mtime1=`stat -c %Y $DIR1/$tfile`
4268
4269         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4270
4271         for (( i=0; i < 2; i++ )) ; do
4272                 local mtime2=`stat -c %Y $DIR1/$tfile`
4273                 [ $mtime2 = $TEST_39_MTIME ] || \
4274                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4275
4276                 cancel_lru_locks $OSC
4277                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4278         done
4279 }
4280 run_test 39e "create, stat, utime, stat ========================"
4281
4282 # bug 21114
4283 test_39f() {
4284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4285
4286         touch $DIR1/$tfile
4287         mtime1=`stat -c %Y $DIR1/$tfile`
4288
4289         sleep 2
4290         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4291
4292         for (( i=0; i < 2; i++ )) ; do
4293                 local mtime2=`stat -c %Y $DIR1/$tfile`
4294                 [ $mtime2 = $TEST_39_MTIME ] || \
4295                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4296
4297                 cancel_lru_locks $OSC
4298                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4299         done
4300 }
4301 run_test 39f "create, stat, sleep, utime, stat ================="
4302
4303 # bug 11063
4304 test_39g() {
4305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4306
4307         echo hello >> $DIR1/$tfile
4308         local mtime1=`stat -c %Y $DIR1/$tfile`
4309
4310         sleep 2
4311         chmod o+r $DIR1/$tfile
4312
4313         for (( i=0; i < 2; i++ )) ; do
4314                 local mtime2=`stat -c %Y $DIR1/$tfile`
4315                 [ "$mtime1" = "$mtime2" ] || \
4316                         error "lost mtime: $mtime2, should be $mtime1"
4317
4318                 cancel_lru_locks $OSC
4319                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4320         done
4321 }
4322 run_test 39g "write, chmod, stat ==============================="
4323
4324 # bug 11063
4325 test_39h() {
4326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4327
4328         touch $DIR1/$tfile
4329         sleep 1
4330
4331         local d1=`date`
4332         echo hello >> $DIR1/$tfile
4333         local mtime1=`stat -c %Y $DIR1/$tfile`
4334
4335         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4336         local d2=`date`
4337         if [ "$d1" != "$d2" ]; then
4338                 echo "write and touch not within one second"
4339         else
4340                 for (( i=0; i < 2; i++ )) ; do
4341                         local mtime2=`stat -c %Y $DIR1/$tfile`
4342                         [ "$mtime2" = $TEST_39_MTIME ] || \
4343                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4344
4345                         cancel_lru_locks $OSC
4346                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4347                 done
4348         fi
4349 }
4350 run_test 39h "write, utime within one second, stat ============="
4351
4352 test_39i() {
4353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4354
4355         touch $DIR1/$tfile
4356         sleep 1
4357
4358         echo hello >> $DIR1/$tfile
4359         local mtime1=`stat -c %Y $DIR1/$tfile`
4360
4361         mv $DIR1/$tfile $DIR1/$tfile-1
4362
4363         for (( i=0; i < 2; i++ )) ; do
4364                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4365
4366                 [ "$mtime1" = "$mtime2" ] || \
4367                         error "lost mtime: $mtime2, should be $mtime1"
4368
4369                 cancel_lru_locks $OSC
4370                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4371         done
4372 }
4373 run_test 39i "write, rename, stat =============================="
4374
4375 test_39j() {
4376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4377
4378         start_full_debug_logging
4379         touch $DIR1/$tfile
4380         sleep 1
4381
4382         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4383         lctl set_param fail_loc=0x80000412
4384         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4385                 error "multiop failed"
4386         local multipid=$!
4387         local mtime1=`stat -c %Y $DIR1/$tfile`
4388
4389         mv $DIR1/$tfile $DIR1/$tfile-1
4390
4391         kill -USR1 $multipid
4392         wait $multipid || error "multiop close failed"
4393
4394         for (( i=0; i < 2; i++ )) ; do
4395                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4396                 [ "$mtime1" = "$mtime2" ] ||
4397                         error "mtime is lost on close: $mtime2, " \
4398                               "should be $mtime1"
4399
4400                 cancel_lru_locks
4401                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4402         done
4403         lctl set_param fail_loc=0
4404         stop_full_debug_logging
4405 }
4406 run_test 39j "write, rename, close, stat ======================="
4407
4408 test_39k() {
4409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4410
4411         touch $DIR1/$tfile
4412         sleep 1
4413
4414         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4415         local multipid=$!
4416         local mtime1=`stat -c %Y $DIR1/$tfile`
4417
4418         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4419
4420         kill -USR1 $multipid
4421         wait $multipid || error "multiop close failed"
4422
4423         for (( i=0; i < 2; i++ )) ; do
4424                 local mtime2=`stat -c %Y $DIR1/$tfile`
4425
4426                 [ "$mtime2" = $TEST_39_MTIME ] || \
4427                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4428
4429                 cancel_lru_locks
4430                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4431         done
4432 }
4433 run_test 39k "write, utime, close, stat ========================"
4434
4435 # this should be set to future
4436 TEST_39_ATIME=`date -d "1 year" +%s`
4437
4438 test_39l() {
4439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4440         remote_mds_nodsh && skip "remote MDS with nodsh"
4441
4442         local atime_diff=$(do_facet $SINGLEMDS \
4443                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4444         rm -rf $DIR/$tdir
4445         mkdir -p $DIR/$tdir
4446
4447         # test setting directory atime to future
4448         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4449         local atime=$(stat -c %X $DIR/$tdir)
4450         [ "$atime" = $TEST_39_ATIME ] ||
4451                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4452
4453         # test setting directory atime from future to now
4454         local now=$(date +%s)
4455         touch -a -d @$now $DIR/$tdir
4456
4457         atime=$(stat -c %X $DIR/$tdir)
4458         [ "$atime" -eq "$now"  ] ||
4459                 error "atime is not updated from future: $atime, $now"
4460
4461         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4462         sleep 3
4463
4464         # test setting directory atime when now > dir atime + atime_diff
4465         local d1=$(date +%s)
4466         ls $DIR/$tdir
4467         local d2=$(date +%s)
4468         cancel_lru_locks mdc
4469         atime=$(stat -c %X $DIR/$tdir)
4470         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4471                 error "atime is not updated  : $atime, should be $d2"
4472
4473         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4474         sleep 3
4475
4476         # test not setting directory atime when now < dir atime + atime_diff
4477         ls $DIR/$tdir
4478         cancel_lru_locks mdc
4479         atime=$(stat -c %X $DIR/$tdir)
4480         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4481                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4482
4483         do_facet $SINGLEMDS \
4484                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4485 }
4486 run_test 39l "directory atime update ==========================="
4487
4488 test_39m() {
4489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4490
4491         touch $DIR1/$tfile
4492         sleep 2
4493         local far_past_mtime=$(date -d "May 29 1953" +%s)
4494         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4495
4496         touch -m -d @$far_past_mtime $DIR1/$tfile
4497         touch -a -d @$far_past_atime $DIR1/$tfile
4498
4499         for (( i=0; i < 2; i++ )) ; do
4500                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4501                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4502                         error "atime or mtime set incorrectly"
4503
4504                 cancel_lru_locks $OSC
4505                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4506         done
4507 }
4508 run_test 39m "test atime and mtime before 1970"
4509
4510 test_39n() { # LU-3832
4511         remote_mds_nodsh && skip "remote MDS with nodsh"
4512
4513         local atime_diff=$(do_facet $SINGLEMDS \
4514                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4515         local atime0
4516         local atime1
4517         local atime2
4518
4519         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4520
4521         rm -rf $DIR/$tfile
4522         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4523         atime0=$(stat -c %X $DIR/$tfile)
4524
4525         sleep 5
4526         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4527         atime1=$(stat -c %X $DIR/$tfile)
4528
4529         sleep 5
4530         cancel_lru_locks mdc
4531         cancel_lru_locks osc
4532         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4533         atime2=$(stat -c %X $DIR/$tfile)
4534
4535         do_facet $SINGLEMDS \
4536                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4537
4538         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4539         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4540 }
4541 run_test 39n "check that O_NOATIME is honored"
4542
4543 test_39o() {
4544         TESTDIR=$DIR/$tdir/$tfile
4545         [ -e $TESTDIR ] && rm -rf $TESTDIR
4546         mkdir -p $TESTDIR
4547         cd $TESTDIR
4548         links1=2
4549         ls
4550         mkdir a b
4551         ls
4552         links2=$(stat -c %h .)
4553         [ $(($links1 + 2)) != $links2 ] &&
4554                 error "wrong links count $(($links1 + 2)) != $links2"
4555         rmdir b
4556         links3=$(stat -c %h .)
4557         [ $(($links1 + 1)) != $links3 ] &&
4558                 error "wrong links count $links1 != $links3"
4559         return 0
4560 }
4561 run_test 39o "directory cached attributes updated after create"
4562
4563 test_39p() {
4564         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4565
4566         local MDTIDX=1
4567         TESTDIR=$DIR/$tdir/$tdir
4568         [ -e $TESTDIR ] && rm -rf $TESTDIR
4569         test_mkdir -p $TESTDIR
4570         cd $TESTDIR
4571         links1=2
4572         ls
4573         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4574         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4575         ls
4576         links2=$(stat -c %h .)
4577         [ $(($links1 + 2)) != $links2 ] &&
4578                 error "wrong links count $(($links1 + 2)) != $links2"
4579         rmdir remote_dir2
4580         links3=$(stat -c %h .)
4581         [ $(($links1 + 1)) != $links3 ] &&
4582                 error "wrong links count $links1 != $links3"
4583         return 0
4584 }
4585 run_test 39p "remote directory cached attributes updated after create ========"
4586
4587 test_39r() {
4588         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4589                 skip "no atime update on old OST"
4590         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4591                 skip_env "ldiskfs only test"
4592         fi
4593
4594         local saved_adiff
4595         saved_adiff=$(do_facet ost1 \
4596                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4597         stack_trap "do_facet ost1 \
4598                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4599
4600         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4601
4602         $LFS setstripe -i 0 $DIR/$tfile
4603         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4604                 error "can't write initial file"
4605         cancel_lru_locks osc
4606
4607         # exceed atime_diff and access file
4608         sleep 6
4609         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4610
4611         local atime_cli=$(stat -c %X $DIR/$tfile)
4612         echo "client atime: $atime_cli"
4613         # allow atime update to be written to device
4614         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4615         sleep 5
4616
4617         local ostdev=$(ostdevname 1)
4618         local fid=($(lfs getstripe -y $DIR/$tfile |
4619                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4620         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4621         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4622
4623         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4624         local atime_ost=$(do_facet ost1 "$cmd" |&
4625                           awk -F'[: ]' '/atime:/ { print $4 }')
4626         (( atime_cli == atime_ost )) ||
4627                 error "atime on client $atime_cli != ost $atime_ost"
4628 }
4629 run_test 39r "lazy atime update on OST"
4630
4631 test_39q() { # LU-8041
4632         local testdir=$DIR/$tdir
4633         mkdir -p $testdir
4634         multiop_bg_pause $testdir D_c || error "multiop failed"
4635         local multipid=$!
4636         cancel_lru_locks mdc
4637         kill -USR1 $multipid
4638         local atime=$(stat -c %X $testdir)
4639         [ "$atime" -ne 0 ] || error "atime is zero"
4640 }
4641 run_test 39q "close won't zero out atime"
4642
4643 test_40() {
4644         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4645         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4646                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4647         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4648                 error "$tfile is not 4096 bytes in size"
4649 }
4650 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4651
4652 test_41() {
4653         # bug 1553
4654         small_write $DIR/f41 18
4655 }
4656 run_test 41 "test small file write + fstat ====================="
4657
4658 count_ost_writes() {
4659         lctl get_param -n ${OSC}.*.stats |
4660                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4661                         END { printf("%0.0f", writes) }'
4662 }
4663
4664 # decent default
4665 WRITEBACK_SAVE=500
4666 DIRTY_RATIO_SAVE=40
4667 MAX_DIRTY_RATIO=50
4668 BG_DIRTY_RATIO_SAVE=10
4669 MAX_BG_DIRTY_RATIO=25
4670
4671 start_writeback() {
4672         trap 0
4673         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4674         # dirty_ratio, dirty_background_ratio
4675         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4676                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4677                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4678                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4679         else
4680                 # if file not here, we are a 2.4 kernel
4681                 kill -CONT `pidof kupdated`
4682         fi
4683 }
4684
4685 stop_writeback() {
4686         # setup the trap first, so someone cannot exit the test at the
4687         # exact wrong time and mess up a machine
4688         trap start_writeback EXIT
4689         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4690         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4691                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4692                 sysctl -w vm.dirty_writeback_centisecs=0
4693                 sysctl -w vm.dirty_writeback_centisecs=0
4694                 # save and increase /proc/sys/vm/dirty_ratio
4695                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4696                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4697                 # save and increase /proc/sys/vm/dirty_background_ratio
4698                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4699                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4700         else
4701                 # if file not here, we are a 2.4 kernel
4702                 kill -STOP `pidof kupdated`
4703         fi
4704 }
4705
4706 # ensure that all stripes have some grant before we test client-side cache
4707 setup_test42() {
4708         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4709                 dd if=/dev/zero of=$i bs=4k count=1
4710                 rm $i
4711         done
4712 }
4713
4714 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4715 # file truncation, and file removal.
4716 test_42a() {
4717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4718
4719         setup_test42
4720         cancel_lru_locks $OSC
4721         stop_writeback
4722         sync; sleep 1; sync # just to be safe
4723         BEFOREWRITES=`count_ost_writes`
4724         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4725         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4726         AFTERWRITES=`count_ost_writes`
4727         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4728                 error "$BEFOREWRITES < $AFTERWRITES"
4729         start_writeback
4730 }
4731 run_test 42a "ensure that we don't flush on close"
4732
4733 test_42b() {
4734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4735
4736         setup_test42
4737         cancel_lru_locks $OSC
4738         stop_writeback
4739         sync
4740         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4741         BEFOREWRITES=$(count_ost_writes)
4742         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4743         AFTERWRITES=$(count_ost_writes)
4744         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4745                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4746         fi
4747         BEFOREWRITES=$(count_ost_writes)
4748         sync || error "sync: $?"
4749         AFTERWRITES=$(count_ost_writes)
4750         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4751                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4752         fi
4753         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4754         start_writeback
4755         return 0
4756 }
4757 run_test 42b "test destroy of file with cached dirty data ======"
4758
4759 # if these tests just want to test the effect of truncation,
4760 # they have to be very careful.  consider:
4761 # - the first open gets a {0,EOF}PR lock
4762 # - the first write conflicts and gets a {0, count-1}PW
4763 # - the rest of the writes are under {count,EOF}PW
4764 # - the open for truncate tries to match a {0,EOF}PR
4765 #   for the filesize and cancels the PWs.
4766 # any number of fixes (don't get {0,EOF} on open, match
4767 # composite locks, do smarter file size management) fix
4768 # this, but for now we want these tests to verify that
4769 # the cancellation with truncate intent works, so we
4770 # start the file with a full-file pw lock to match against
4771 # until the truncate.
4772 trunc_test() {
4773         test=$1
4774         file=$DIR/$test
4775         offset=$2
4776         cancel_lru_locks $OSC
4777         stop_writeback
4778         # prime the file with 0,EOF PW to match
4779         touch $file
4780         $TRUNCATE $file 0
4781         sync; sync
4782         # now the real test..
4783         dd if=/dev/zero of=$file bs=1024 count=100
4784         BEFOREWRITES=`count_ost_writes`
4785         $TRUNCATE $file $offset
4786         cancel_lru_locks $OSC
4787         AFTERWRITES=`count_ost_writes`
4788         start_writeback
4789 }
4790
4791 test_42c() {
4792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4793
4794         trunc_test 42c 1024
4795         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4796                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4797         rm $file
4798 }
4799 run_test 42c "test partial truncate of file with cached dirty data"
4800
4801 test_42d() {
4802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4803
4804         trunc_test 42d 0
4805         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4806                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4807         rm $file
4808 }
4809 run_test 42d "test complete truncate of file with cached dirty data"
4810
4811 test_42e() { # bug22074
4812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4813
4814         local TDIR=$DIR/${tdir}e
4815         local pages=16 # hardcoded 16 pages, don't change it.
4816         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4817         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4818         local max_dirty_mb
4819         local warmup_files
4820
4821         test_mkdir $DIR/${tdir}e
4822         $LFS setstripe -c 1 $TDIR
4823         createmany -o $TDIR/f $files
4824
4825         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4826
4827         # we assume that with $OSTCOUNT files, at least one of them will
4828         # be allocated on OST0.
4829         warmup_files=$((OSTCOUNT * max_dirty_mb))
4830         createmany -o $TDIR/w $warmup_files
4831
4832         # write a large amount of data into one file and sync, to get good
4833         # avail_grant number from OST.
4834         for ((i=0; i<$warmup_files; i++)); do
4835                 idx=$($LFS getstripe -i $TDIR/w$i)
4836                 [ $idx -ne 0 ] && continue
4837                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4838                 break
4839         done
4840         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4841         sync
4842         $LCTL get_param $proc_osc0/cur_dirty_bytes
4843         $LCTL get_param $proc_osc0/cur_grant_bytes
4844
4845         # create as much dirty pages as we can while not to trigger the actual
4846         # RPCs directly. but depends on the env, VFS may trigger flush during this
4847         # period, hopefully we are good.
4848         for ((i=0; i<$warmup_files; i++)); do
4849                 idx=$($LFS getstripe -i $TDIR/w$i)
4850                 [ $idx -ne 0 ] && continue
4851                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4852         done
4853         $LCTL get_param $proc_osc0/cur_dirty_bytes
4854         $LCTL get_param $proc_osc0/cur_grant_bytes
4855
4856         # perform the real test
4857         $LCTL set_param $proc_osc0/rpc_stats 0
4858         for ((;i<$files; i++)); do
4859                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4860                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4861         done
4862         sync
4863         $LCTL get_param $proc_osc0/rpc_stats
4864
4865         local percent=0
4866         local have_ppr=false
4867         $LCTL get_param $proc_osc0/rpc_stats |
4868                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4869                         # skip lines until we are at the RPC histogram data
4870                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4871                         $have_ppr || continue
4872
4873                         # we only want the percent stat for < 16 pages
4874                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4875
4876                         percent=$((percent + WPCT))
4877                         if [[ $percent -gt 15 ]]; then
4878                                 error "less than 16-pages write RPCs" \
4879                                       "$percent% > 15%"
4880                                 break
4881                         fi
4882                 done
4883         rm -rf $TDIR
4884 }
4885 run_test 42e "verify sub-RPC writes are not done synchronously"
4886
4887 test_43A() { # was test_43
4888         test_mkdir $DIR/$tdir
4889         cp -p /bin/ls $DIR/$tdir/$tfile
4890         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4891         pid=$!
4892         # give multiop a chance to open
4893         sleep 1
4894
4895         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4896         kill -USR1 $pid
4897         # Wait for multiop to exit
4898         wait $pid
4899 }
4900 run_test 43A "execution of file opened for write should return -ETXTBSY"
4901
4902 test_43a() {
4903         test_mkdir $DIR/$tdir
4904         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4905         $DIR/$tdir/sleep 60 &
4906         SLEEP_PID=$!
4907         # Make sure exec of $tdir/sleep wins race with truncate
4908         sleep 1
4909         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4910         kill $SLEEP_PID
4911 }
4912 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4913
4914 test_43b() {
4915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4916
4917         test_mkdir $DIR/$tdir
4918         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4919         $DIR/$tdir/sleep 60 &
4920         SLEEP_PID=$!
4921         # Make sure exec of $tdir/sleep wins race with truncate
4922         sleep 1
4923         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4924         kill $SLEEP_PID
4925 }
4926 run_test 43b "truncate of file being executed should return -ETXTBSY"
4927
4928 test_43c() {
4929         local testdir="$DIR/$tdir"
4930         test_mkdir $testdir
4931         cp $SHELL $testdir/
4932         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4933                 ( cd $testdir && md5sum -c )
4934 }
4935 run_test 43c "md5sum of copy into lustre"
4936
4937 test_44A() { # was test_44
4938         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4939
4940         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4941         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4942 }
4943 run_test 44A "zero length read from a sparse stripe"
4944
4945 test_44a() {
4946         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4947                 awk '{ print $2 }')
4948         [ -z "$nstripe" ] && skip "can't get stripe info"
4949         [[ $nstripe -gt $OSTCOUNT ]] &&
4950                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4951
4952         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4953                 awk '{ print $2 }')
4954         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4955                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4956                         awk '{ print $2 }')
4957         fi
4958
4959         OFFSETS="0 $((stride/2)) $((stride-1))"
4960         for offset in $OFFSETS; do
4961                 for i in $(seq 0 $((nstripe-1))); do
4962                         local GLOBALOFFSETS=""
4963                         # size in Bytes
4964                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4965                         local myfn=$DIR/d44a-$size
4966                         echo "--------writing $myfn at $size"
4967                         ll_sparseness_write $myfn $size ||
4968                                 error "ll_sparseness_write"
4969                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4970                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4971                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4972
4973                         for j in $(seq 0 $((nstripe-1))); do
4974                                 # size in Bytes
4975                                 size=$((((j + $nstripe )*$stride + $offset)))
4976                                 ll_sparseness_write $myfn $size ||
4977                                         error "ll_sparseness_write"
4978                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4979                         done
4980                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4981                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4982                         rm -f $myfn
4983                 done
4984         done
4985 }
4986 run_test 44a "test sparse pwrite ==============================="
4987
4988 dirty_osc_total() {
4989         tot=0
4990         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4991                 tot=$(($tot + $d))
4992         done
4993         echo $tot
4994 }
4995 do_dirty_record() {
4996         before=`dirty_osc_total`
4997         echo executing "\"$*\""
4998         eval $*
4999         after=`dirty_osc_total`
5000         echo before $before, after $after
5001 }
5002 test_45() {
5003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5004
5005         f="$DIR/f45"
5006         # Obtain grants from OST if it supports it
5007         echo blah > ${f}_grant
5008         stop_writeback
5009         sync
5010         do_dirty_record "echo blah > $f"
5011         [[ $before -eq $after ]] && error "write wasn't cached"
5012         do_dirty_record "> $f"
5013         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5014         do_dirty_record "echo blah > $f"
5015         [[ $before -eq $after ]] && error "write wasn't cached"
5016         do_dirty_record "sync"
5017         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5018         do_dirty_record "echo blah > $f"
5019         [[ $before -eq $after ]] && error "write wasn't cached"
5020         do_dirty_record "cancel_lru_locks osc"
5021         [[ $before -gt $after ]] ||
5022                 error "lock cancellation didn't lower dirty count"
5023         start_writeback
5024 }
5025 run_test 45 "osc io page accounting ============================"
5026
5027 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5028 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5029 # objects offset and an assert hit when an rpc was built with 1023's mapped
5030 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5031 test_46() {
5032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5033
5034         f="$DIR/f46"
5035         stop_writeback
5036         sync
5037         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5038         sync
5039         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5040         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5041         sync
5042         start_writeback
5043 }
5044 run_test 46 "dirtying a previously written page ================"
5045
5046 # test_47 is removed "Device nodes check" is moved to test_28
5047
5048 test_48a() { # bug 2399
5049         [ "$mds1_FSTYPE" = "zfs" ] &&
5050         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5051                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5052
5053         test_mkdir $DIR/$tdir
5054         cd $DIR/$tdir
5055         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5056         test_mkdir $DIR/$tdir
5057         touch foo || error "'touch foo' failed after recreating cwd"
5058         test_mkdir bar
5059         touch .foo || error "'touch .foo' failed after recreating cwd"
5060         test_mkdir .bar
5061         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5062         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5063         cd . || error "'cd .' failed after recreating cwd"
5064         mkdir . && error "'mkdir .' worked after recreating cwd"
5065         rmdir . && error "'rmdir .' worked after recreating cwd"
5066         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5067         cd .. || error "'cd ..' failed after recreating cwd"
5068 }
5069 run_test 48a "Access renamed working dir (should return errors)="
5070
5071 test_48b() { # bug 2399
5072         rm -rf $DIR/$tdir
5073         test_mkdir $DIR/$tdir
5074         cd $DIR/$tdir
5075         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5076         touch foo && error "'touch foo' worked after removing cwd"
5077         mkdir foo && error "'mkdir foo' worked after removing cwd"
5078         touch .foo && error "'touch .foo' worked after removing cwd"
5079         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5080         ls . > /dev/null && error "'ls .' worked after removing cwd"
5081         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5082         mkdir . && error "'mkdir .' worked after removing cwd"
5083         rmdir . && error "'rmdir .' worked after removing cwd"
5084         ln -s . foo && error "'ln -s .' worked after removing cwd"
5085         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5086 }
5087 run_test 48b "Access removed working dir (should return errors)="
5088
5089 test_48c() { # bug 2350
5090         #lctl set_param debug=-1
5091         #set -vx
5092         rm -rf $DIR/$tdir
5093         test_mkdir -p $DIR/$tdir/dir
5094         cd $DIR/$tdir/dir
5095         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5096         $TRACE touch foo && error "touch foo worked after removing cwd"
5097         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5098         touch .foo && error "touch .foo worked after removing cwd"
5099         mkdir .foo && error "mkdir .foo worked after removing cwd"
5100         $TRACE ls . && error "'ls .' worked after removing cwd"
5101         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5102         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5103         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5104         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5105         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5106 }
5107 run_test 48c "Access removed working subdir (should return errors)"
5108
5109 test_48d() { # bug 2350
5110         #lctl set_param debug=-1
5111         #set -vx
5112         rm -rf $DIR/$tdir
5113         test_mkdir -p $DIR/$tdir/dir
5114         cd $DIR/$tdir/dir
5115         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5116         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5117         $TRACE touch foo && error "'touch foo' worked after removing parent"
5118         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5119         touch .foo && error "'touch .foo' worked after removing parent"
5120         mkdir .foo && error "mkdir .foo worked after removing parent"
5121         $TRACE ls . && error "'ls .' worked after removing parent"
5122         $TRACE ls .. && error "'ls ..' worked after removing parent"
5123         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5124         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5125         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5126         true
5127 }
5128 run_test 48d "Access removed parent subdir (should return errors)"
5129
5130 test_48e() { # bug 4134
5131         #lctl set_param debug=-1
5132         #set -vx
5133         rm -rf $DIR/$tdir
5134         test_mkdir -p $DIR/$tdir/dir
5135         cd $DIR/$tdir/dir
5136         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5137         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5138         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5139         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5140         # On a buggy kernel addition of "touch foo" after cd .. will
5141         # produce kernel oops in lookup_hash_it
5142         touch ../foo && error "'cd ..' worked after recreate parent"
5143         cd $DIR
5144         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5145 }
5146 run_test 48e "Access to recreated parent subdir (should return errors)"
5147
5148 test_48f() {
5149         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5150                 skip "need MDS >= 2.13.55"
5151         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5152         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5153                 skip "needs different host for mdt1 mdt2"
5154         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5155
5156         $LFS mkdir -i0 $DIR/$tdir
5157         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5158
5159         for d in sub1 sub2 sub3; do
5160                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5161                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5162                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5163         done
5164
5165         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5166 }
5167 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5168
5169 test_49() { # LU-1030
5170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5171         remote_ost_nodsh && skip "remote OST with nodsh"
5172
5173         # get ost1 size - $FSNAME-OST0000
5174         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5175                 awk '{ print $4 }')
5176         # write 800M at maximum
5177         [[ $ost1_size -lt 2 ]] && ost1_size=2
5178         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5179
5180         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5181         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5182         local dd_pid=$!
5183
5184         # change max_pages_per_rpc while writing the file
5185         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5186         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5187         # loop until dd process exits
5188         while ps ax -opid | grep -wq $dd_pid; do
5189                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5190                 sleep $((RANDOM % 5 + 1))
5191         done
5192         # restore original max_pages_per_rpc
5193         $LCTL set_param $osc1_mppc=$orig_mppc
5194         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5195 }
5196 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5197
5198 test_50() {
5199         # bug 1485
5200         test_mkdir $DIR/$tdir
5201         cd $DIR/$tdir
5202         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5203 }
5204 run_test 50 "special situations: /proc symlinks  ==============="
5205
5206 test_51a() {    # was test_51
5207         # bug 1516 - create an empty entry right after ".." then split dir
5208         test_mkdir -c1 $DIR/$tdir
5209         touch $DIR/$tdir/foo
5210         $MCREATE $DIR/$tdir/bar
5211         rm $DIR/$tdir/foo
5212         createmany -m $DIR/$tdir/longfile 201
5213         FNUM=202
5214         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5215                 $MCREATE $DIR/$tdir/longfile$FNUM
5216                 FNUM=$(($FNUM + 1))
5217                 echo -n "+"
5218         done
5219         echo
5220         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5221 }
5222 run_test 51a "special situations: split htree with empty entry =="
5223
5224 cleanup_print_lfs_df () {
5225         trap 0
5226         $LFS df
5227         $LFS df -i
5228 }
5229
5230 test_51b() {
5231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5232
5233         local dir=$DIR/$tdir
5234         local nrdirs=$((65536 + 100))
5235
5236         # cleanup the directory
5237         rm -fr $dir
5238
5239         test_mkdir -c1 $dir
5240
5241         $LFS df
5242         $LFS df -i
5243         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5244         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5245         [[ $numfree -lt $nrdirs ]] &&
5246                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5247
5248         # need to check free space for the directories as well
5249         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5250         numfree=$(( blkfree / $(fs_inode_ksize) ))
5251         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5252
5253         trap cleanup_print_lfs_df EXIT
5254
5255         # create files
5256         createmany -d $dir/d $nrdirs || {
5257                 unlinkmany $dir/d $nrdirs
5258                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5259         }
5260
5261         # really created :
5262         nrdirs=$(ls -U $dir | wc -l)
5263
5264         # unlink all but 100 subdirectories, then check it still works
5265         local left=100
5266         local delete=$((nrdirs - left))
5267
5268         $LFS df
5269         $LFS df -i
5270
5271         # for ldiskfs the nlink count should be 1, but this is OSD specific
5272         # and so this is listed for informational purposes only
5273         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5274         unlinkmany -d $dir/d $delete ||
5275                 error "unlink of first $delete subdirs failed"
5276
5277         echo "nlink between: $(stat -c %h $dir)"
5278         local found=$(ls -U $dir | wc -l)
5279         [ $found -ne $left ] &&
5280                 error "can't find subdirs: found only $found, expected $left"
5281
5282         unlinkmany -d $dir/d $delete $left ||
5283                 error "unlink of second $left subdirs failed"
5284         # regardless of whether the backing filesystem tracks nlink accurately
5285         # or not, the nlink count shouldn't be more than "." and ".." here
5286         local after=$(stat -c %h $dir)
5287         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5288                 echo "nlink after: $after"
5289
5290         cleanup_print_lfs_df
5291 }
5292 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5293
5294 test_51d() {
5295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5296         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5297
5298         test_mkdir $DIR/$tdir
5299         createmany -o $DIR/$tdir/t- 1000
5300         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5301         for N in $(seq 0 $((OSTCOUNT - 1))); do
5302                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5303                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5304                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5305                         '($1 == '$N') { objs += 1 } \
5306                         END { printf("%0.0f", objs) }')
5307                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5308         done
5309         unlinkmany $DIR/$tdir/t- 1000
5310
5311         NLAST=0
5312         for N in $(seq 1 $((OSTCOUNT - 1))); do
5313                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5314                         error "OST $N has less objects vs OST $NLAST" \
5315                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5316                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5317                         error "OST $N has less objects vs OST $NLAST" \
5318                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5319
5320                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5321                         error "OST $N has less #0 objects vs OST $NLAST" \
5322                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5323                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5324                         error "OST $N has less #0 objects vs OST $NLAST" \
5325                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5326                 NLAST=$N
5327         done
5328         rm -f $TMP/$tfile
5329 }
5330 run_test 51d "check object distribution"
5331
5332 test_51e() {
5333         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5334                 skip_env "ldiskfs only test"
5335         fi
5336
5337         test_mkdir -c1 $DIR/$tdir
5338         test_mkdir -c1 $DIR/$tdir/d0
5339
5340         touch $DIR/$tdir/d0/foo
5341         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5342                 error "file exceed 65000 nlink limit!"
5343         unlinkmany $DIR/$tdir/d0/f- 65001
5344         return 0
5345 }
5346 run_test 51e "check file nlink limit"
5347
5348 test_51f() {
5349         test_mkdir $DIR/$tdir
5350
5351         local max=100000
5352         local ulimit_old=$(ulimit -n)
5353         local spare=20 # number of spare fd's for scripts/libraries, etc.
5354         local mdt=$($LFS getstripe -m $DIR/$tdir)
5355         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5356
5357         echo "MDT$mdt numfree=$numfree, max=$max"
5358         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5359         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5360                 while ! ulimit -n $((numfree + spare)); do
5361                         numfree=$((numfree * 3 / 4))
5362                 done
5363                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5364         else
5365                 echo "left ulimit at $ulimit_old"
5366         fi
5367
5368         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5369                 unlinkmany $DIR/$tdir/f $numfree
5370                 error "create+open $numfree files in $DIR/$tdir failed"
5371         }
5372         ulimit -n $ulimit_old
5373
5374         # if createmany exits at 120s there will be fewer than $numfree files
5375         unlinkmany $DIR/$tdir/f $numfree || true
5376 }
5377 run_test 51f "check many open files limit"
5378
5379 test_52a() {
5380         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5381         test_mkdir $DIR/$tdir
5382         touch $DIR/$tdir/foo
5383         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5384         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5385         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5386         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5387         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5388                                         error "link worked"
5389         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5390         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5391         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5392                                                      error "lsattr"
5393         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5394         cp -r $DIR/$tdir $TMP/
5395         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5396 }
5397 run_test 52a "append-only flag test (should return errors)"
5398
5399 test_52b() {
5400         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5401         test_mkdir $DIR/$tdir
5402         touch $DIR/$tdir/foo
5403         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5404         cat test > $DIR/$tdir/foo && error "cat test worked"
5405         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5406         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5407         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5408                                         error "link worked"
5409         echo foo >> $DIR/$tdir/foo && error "echo worked"
5410         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5411         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5412         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5413         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5414                                                         error "lsattr"
5415         chattr -i $DIR/$tdir/foo || error "chattr failed"
5416
5417         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5418 }
5419 run_test 52b "immutable flag test (should return errors) ======="
5420
5421 test_53() {
5422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5423         remote_mds_nodsh && skip "remote MDS with nodsh"
5424         remote_ost_nodsh && skip "remote OST with nodsh"
5425
5426         local param
5427         local param_seq
5428         local ostname
5429         local mds_last
5430         local mds_last_seq
5431         local ost_last
5432         local ost_last_seq
5433         local ost_last_id
5434         local ostnum
5435         local node
5436         local found=false
5437         local support_last_seq=true
5438
5439         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5440                 support_last_seq=false
5441
5442         # only test MDT0000
5443         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5444         local value
5445         for value in $(do_facet $SINGLEMDS \
5446                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5447                 param=$(echo ${value[0]} | cut -d "=" -f1)
5448                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5449
5450                 if $support_last_seq; then
5451                         param_seq=$(echo $param |
5452                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5453                         mds_last_seq=$(do_facet $SINGLEMDS \
5454                                        $LCTL get_param -n $param_seq)
5455                 fi
5456                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5457
5458                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5459                 node=$(facet_active_host ost$((ostnum+1)))
5460                 param="obdfilter.$ostname.last_id"
5461                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5462                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5463                         ost_last_id=$ost_last
5464
5465                         if $support_last_seq; then
5466                                 ost_last_id=$(echo $ost_last |
5467                                               awk -F':' '{print $2}' |
5468                                               sed -e "s/^0x//g")
5469                                 ost_last_seq=$(echo $ost_last |
5470                                                awk -F':' '{print $1}')
5471                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5472                         fi
5473
5474                         if [[ $ost_last_id != $mds_last ]]; then
5475                                 error "$ost_last_id != $mds_last"
5476                         else
5477                                 found=true
5478                                 break
5479                         fi
5480                 done
5481         done
5482         $found || error "can not match last_seq/last_id for $mdtosc"
5483         return 0
5484 }
5485 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5486
5487 test_54a() {
5488         perl -MSocket -e ';' || skip "no Socket perl module installed"
5489
5490         $SOCKETSERVER $DIR/socket ||
5491                 error "$SOCKETSERVER $DIR/socket failed: $?"
5492         $SOCKETCLIENT $DIR/socket ||
5493                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5494         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5495 }
5496 run_test 54a "unix domain socket test =========================="
5497
5498 test_54b() {
5499         f="$DIR/f54b"
5500         mknod $f c 1 3
5501         chmod 0666 $f
5502         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5503 }
5504 run_test 54b "char device works in lustre ======================"
5505
5506 find_loop_dev() {
5507         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5508         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5509         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5510
5511         for i in $(seq 3 7); do
5512                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5513                 LOOPDEV=$LOOPBASE$i
5514                 LOOPNUM=$i
5515                 break
5516         done
5517 }
5518
5519 cleanup_54c() {
5520         local rc=0
5521         loopdev="$DIR/loop54c"
5522
5523         trap 0
5524         $UMOUNT $DIR/$tdir || rc=$?
5525         losetup -d $loopdev || true
5526         losetup -d $LOOPDEV || true
5527         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5528         return $rc
5529 }
5530
5531 test_54c() {
5532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5533
5534         loopdev="$DIR/loop54c"
5535
5536         find_loop_dev
5537         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5538         trap cleanup_54c EXIT
5539         mknod $loopdev b 7 $LOOPNUM
5540         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5541         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5542         losetup $loopdev $DIR/$tfile ||
5543                 error "can't set up $loopdev for $DIR/$tfile"
5544         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5545         test_mkdir $DIR/$tdir
5546         mount -t ext2 $loopdev $DIR/$tdir ||
5547                 error "error mounting $loopdev on $DIR/$tdir"
5548         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5549                 error "dd write"
5550         df $DIR/$tdir
5551         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5552                 error "dd read"
5553         cleanup_54c
5554 }
5555 run_test 54c "block device works in lustre ====================="
5556
5557 test_54d() {
5558         f="$DIR/f54d"
5559         string="aaaaaa"
5560         mknod $f p
5561         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5562 }
5563 run_test 54d "fifo device works in lustre ======================"
5564
5565 test_54e() {
5566         f="$DIR/f54e"
5567         string="aaaaaa"
5568         cp -aL /dev/console $f
5569         echo $string > $f || error "echo $string to $f failed"
5570 }
5571 run_test 54e "console/tty device works in lustre ======================"
5572
5573 test_56a() {
5574         local numfiles=3
5575         local dir=$DIR/$tdir
5576
5577         rm -rf $dir
5578         test_mkdir -p $dir/dir
5579         for i in $(seq $numfiles); do
5580                 touch $dir/file$i
5581                 touch $dir/dir/file$i
5582         done
5583
5584         local numcomp=$($LFS getstripe --component-count $dir)
5585
5586         [[ $numcomp == 0 ]] && numcomp=1
5587
5588         # test lfs getstripe with --recursive
5589         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5590
5591         [[ $filenum -eq $((numfiles * 2)) ]] ||
5592                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5593         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5594         [[ $filenum -eq $numfiles ]] ||
5595                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5596         echo "$LFS getstripe showed obdidx or l_ost_idx"
5597
5598         # test lfs getstripe with file instead of dir
5599         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5600         [[ $filenum -eq 1 ]] ||
5601                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5602         echo "$LFS getstripe file1 passed"
5603
5604         #test lfs getstripe with --verbose
5605         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5606         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5607                 error "$LFS getstripe --verbose $dir: "\
5608                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5609         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5610                 error "$LFS getstripe $dir: showed lmm_magic"
5611
5612         #test lfs getstripe with -v prints lmm_fid
5613         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5614         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5615                 error "$LFS getstripe -v $dir: "\
5616                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5617         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5618                 error "$LFS getstripe $dir: showed lmm_fid by default"
5619         echo "$LFS getstripe --verbose passed"
5620
5621         #check for FID information
5622         local fid1=$($LFS getstripe --fid $dir/file1)
5623         local fid2=$($LFS getstripe --verbose $dir/file1 |
5624                      awk '/lmm_fid: / { print $2; exit; }')
5625         local fid3=$($LFS path2fid $dir/file1)
5626
5627         [ "$fid1" != "$fid2" ] &&
5628                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5629         [ "$fid1" != "$fid3" ] &&
5630                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5631         echo "$LFS getstripe --fid passed"
5632
5633         #test lfs getstripe with --obd
5634         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5635                 error "$LFS getstripe --obd wrong_uuid: should return error"
5636
5637         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5638
5639         local ostidx=1
5640         local obduuid=$(ostuuid_from_index $ostidx)
5641         local found=$($LFS getstripe -r --obd $obduuid $dir |
5642                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5643
5644         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5645         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5646                 ((filenum--))
5647         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5648                 ((filenum--))
5649
5650         [[ $found -eq $filenum ]] ||
5651                 error "$LFS getstripe --obd: found $found expect $filenum"
5652         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5653                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5654                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5655                 error "$LFS getstripe --obd: should not show file on other obd"
5656         echo "$LFS getstripe --obd passed"
5657 }
5658 run_test 56a "check $LFS getstripe"
5659
5660 test_56b() {
5661         local dir=$DIR/$tdir
5662         local numdirs=3
5663
5664         test_mkdir $dir
5665         for i in $(seq $numdirs); do
5666                 test_mkdir $dir/dir$i
5667         done
5668
5669         # test lfs getdirstripe default mode is non-recursion, which is
5670         # different from lfs getstripe
5671         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5672
5673         [[ $dircnt -eq 1 ]] ||
5674                 error "$LFS getdirstripe: found $dircnt, not 1"
5675         dircnt=$($LFS getdirstripe --recursive $dir |
5676                 grep -c lmv_stripe_count)
5677         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5678                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5679 }
5680 run_test 56b "check $LFS getdirstripe"
5681
5682 test_56c() {
5683         remote_ost_nodsh && skip "remote OST with nodsh"
5684
5685         local ost_idx=0
5686         local ost_name=$(ostname_from_index $ost_idx)
5687         local old_status=$(ost_dev_status $ost_idx)
5688         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5689
5690         [[ -z "$old_status" ]] ||
5691                 skip_env "OST $ost_name is in $old_status status"
5692
5693         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5694         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5695                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5696         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5697                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5698                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5699         fi
5700
5701         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5702                 error "$LFS df -v showing inactive devices"
5703         sleep_maxage
5704
5705         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5706
5707         [[ "$new_status" =~ "D" ]] ||
5708                 error "$ost_name status is '$new_status', missing 'D'"
5709         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5710                 [[ "$new_status" =~ "N" ]] ||
5711                         error "$ost_name status is '$new_status', missing 'N'"
5712         fi
5713         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5714                 [[ "$new_status" =~ "f" ]] ||
5715                         error "$ost_name status is '$new_status', missing 'f'"
5716         fi
5717
5718         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5719         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5720                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5721         [[ -z "$p" ]] && restore_lustre_params < $p || true
5722         sleep_maxage
5723
5724         new_status=$(ost_dev_status $ost_idx)
5725         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5726                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5727         # can't check 'f' as devices may actually be on flash
5728 }
5729 run_test 56c "check 'lfs df' showing device status"
5730
5731 test_56d() {
5732         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5733         local osts=$($LFS df -v $MOUNT | grep -c OST)
5734
5735         $LFS df $MOUNT
5736
5737         (( mdts == MDSCOUNT )) ||
5738                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5739         (( osts == OSTCOUNT )) ||
5740                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5741 }
5742 run_test 56d "'lfs df -v' prints only configured devices"
5743
5744 NUMFILES=3
5745 NUMDIRS=3
5746 setup_56() {
5747         local local_tdir="$1"
5748         local local_numfiles="$2"
5749         local local_numdirs="$3"
5750         local dir_params="$4"
5751         local dir_stripe_params="$5"
5752
5753         if [ ! -d "$local_tdir" ] ; then
5754                 test_mkdir -p $dir_stripe_params $local_tdir
5755                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5756                 for i in $(seq $local_numfiles) ; do
5757                         touch $local_tdir/file$i
5758                 done
5759                 for i in $(seq $local_numdirs) ; do
5760                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5761                         for j in $(seq $local_numfiles) ; do
5762                                 touch $local_tdir/dir$i/file$j
5763                         done
5764                 done
5765         fi
5766 }
5767
5768 setup_56_special() {
5769         local local_tdir=$1
5770         local local_numfiles=$2
5771         local local_numdirs=$3
5772
5773         setup_56 $local_tdir $local_numfiles $local_numdirs
5774
5775         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5776                 for i in $(seq $local_numfiles) ; do
5777                         mknod $local_tdir/loop${i}b b 7 $i
5778                         mknod $local_tdir/null${i}c c 1 3
5779                         ln -s $local_tdir/file1 $local_tdir/link${i}
5780                 done
5781                 for i in $(seq $local_numdirs) ; do
5782                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5783                         mknod $local_tdir/dir$i/null${i}c c 1 3
5784                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5785                 done
5786         fi
5787 }
5788
5789 test_56g() {
5790         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5791         local expected=$(($NUMDIRS + 2))
5792
5793         setup_56 $dir $NUMFILES $NUMDIRS
5794
5795         # test lfs find with -name
5796         for i in $(seq $NUMFILES) ; do
5797                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5798
5799                 [ $nums -eq $expected ] ||
5800                         error "lfs find -name '*$i' $dir wrong: "\
5801                               "found $nums, expected $expected"
5802         done
5803 }
5804 run_test 56g "check lfs find -name"
5805
5806 test_56h() {
5807         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5808         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5809
5810         setup_56 $dir $NUMFILES $NUMDIRS
5811
5812         # test lfs find with ! -name
5813         for i in $(seq $NUMFILES) ; do
5814                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5815
5816                 [ $nums -eq $expected ] ||
5817                         error "lfs find ! -name '*$i' $dir wrong: "\
5818                               "found $nums, expected $expected"
5819         done
5820 }
5821 run_test 56h "check lfs find ! -name"
5822
5823 test_56i() {
5824         local dir=$DIR/$tdir
5825
5826         test_mkdir $dir
5827
5828         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5829         local out=$($cmd)
5830
5831         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5832 }
5833 run_test 56i "check 'lfs find -ost UUID' skips directories"
5834
5835 test_56j() {
5836         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5837
5838         setup_56_special $dir $NUMFILES $NUMDIRS
5839
5840         local expected=$((NUMDIRS + 1))
5841         local cmd="$LFS find -type d $dir"
5842         local nums=$($cmd | wc -l)
5843
5844         [ $nums -eq $expected ] ||
5845                 error "'$cmd' wrong: found $nums, expected $expected"
5846 }
5847 run_test 56j "check lfs find -type d"
5848
5849 test_56k() {
5850         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5851
5852         setup_56_special $dir $NUMFILES $NUMDIRS
5853
5854         local expected=$(((NUMDIRS + 1) * NUMFILES))
5855         local cmd="$LFS find -type f $dir"
5856         local nums=$($cmd | wc -l)
5857
5858         [ $nums -eq $expected ] ||
5859                 error "'$cmd' wrong: found $nums, expected $expected"
5860 }
5861 run_test 56k "check lfs find -type f"
5862
5863 test_56l() {
5864         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5865
5866         setup_56_special $dir $NUMFILES $NUMDIRS
5867
5868         local expected=$((NUMDIRS + NUMFILES))
5869         local cmd="$LFS find -type b $dir"
5870         local nums=$($cmd | wc -l)
5871
5872         [ $nums -eq $expected ] ||
5873                 error "'$cmd' wrong: found $nums, expected $expected"
5874 }
5875 run_test 56l "check lfs find -type b"
5876
5877 test_56m() {
5878         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5879
5880         setup_56_special $dir $NUMFILES $NUMDIRS
5881
5882         local expected=$((NUMDIRS + NUMFILES))
5883         local cmd="$LFS find -type c $dir"
5884         local nums=$($cmd | wc -l)
5885         [ $nums -eq $expected ] ||
5886                 error "'$cmd' wrong: found $nums, expected $expected"
5887 }
5888 run_test 56m "check lfs find -type c"
5889
5890 test_56n() {
5891         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5892         setup_56_special $dir $NUMFILES $NUMDIRS
5893
5894         local expected=$((NUMDIRS + NUMFILES))
5895         local cmd="$LFS find -type l $dir"
5896         local nums=$($cmd | wc -l)
5897
5898         [ $nums -eq $expected ] ||
5899                 error "'$cmd' wrong: found $nums, expected $expected"
5900 }
5901 run_test 56n "check lfs find -type l"
5902
5903 test_56o() {
5904         local dir=$DIR/$tdir
5905
5906         setup_56 $dir $NUMFILES $NUMDIRS
5907         utime $dir/file1 > /dev/null || error "utime (1)"
5908         utime $dir/file2 > /dev/null || error "utime (2)"
5909         utime $dir/dir1 > /dev/null || error "utime (3)"
5910         utime $dir/dir2 > /dev/null || error "utime (4)"
5911         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5912         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5913
5914         local expected=4
5915         local nums=$($LFS find -mtime +0 $dir | wc -l)
5916
5917         [ $nums -eq $expected ] ||
5918                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5919
5920         expected=12
5921         cmd="$LFS find -mtime 0 $dir"
5922         nums=$($cmd | wc -l)
5923         [ $nums -eq $expected ] ||
5924                 error "'$cmd' wrong: found $nums, expected $expected"
5925 }
5926 run_test 56o "check lfs find -mtime for old files"
5927
5928 test_56ob() {
5929         local dir=$DIR/$tdir
5930         local expected=1
5931         local count=0
5932
5933         # just to make sure there is something that won't be found
5934         test_mkdir $dir
5935         touch $dir/$tfile.now
5936
5937         for age in year week day hour min; do
5938                 count=$((count + 1))
5939
5940                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5941                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5942                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5943
5944                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5945                 local nums=$($cmd | wc -l)
5946                 [ $nums -eq $expected ] ||
5947                         error "'$cmd' wrong: found $nums, expected $expected"
5948
5949                 cmd="$LFS find $dir -atime $count${age:0:1}"
5950                 nums=$($cmd | wc -l)
5951                 [ $nums -eq $expected ] ||
5952                         error "'$cmd' wrong: found $nums, expected $expected"
5953         done
5954
5955         sleep 2
5956         cmd="$LFS find $dir -ctime +1s -type f"
5957         nums=$($cmd | wc -l)
5958         (( $nums == $count * 2 + 1)) ||
5959                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5960 }
5961 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5962
5963 test_newerXY_base() {
5964         local x=$1
5965         local y=$2
5966         local dir=$DIR/$tdir
5967         local ref
5968         local negref
5969
5970         if [ $y == "t" ]; then
5971                 if [ $x == "b" ]; then
5972                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5973                 else
5974                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5975                 fi
5976         else
5977                 ref=$DIR/$tfile.newer.$x$y
5978                 touch $ref || error "touch $ref failed"
5979         fi
5980
5981         echo "before = $ref"
5982         sleep 2
5983         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5984         sleep 2
5985         if [ $y == "t" ]; then
5986                 if [ $x == "b" ]; then
5987                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5988                 else
5989                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5990                 fi
5991         else
5992                 negref=$DIR/$tfile.negnewer.$x$y
5993                 touch $negref || error "touch $negref failed"
5994         fi
5995
5996         echo "after = $negref"
5997         local cmd="$LFS find $dir -newer$x$y $ref"
5998         local nums=$(eval $cmd | wc -l)
5999         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6000
6001         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6002                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6003
6004         cmd="$LFS find $dir ! -newer$x$y $negref"
6005         nums=$(eval $cmd | wc -l)
6006         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6007                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6008
6009         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6010         nums=$(eval $cmd | wc -l)
6011         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6012                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6013
6014         rm -rf $DIR/*
6015 }
6016
6017 test_56oc() {
6018         test_newerXY_base "a" "a"
6019         test_newerXY_base "a" "m"
6020         test_newerXY_base "a" "c"
6021         test_newerXY_base "m" "a"
6022         test_newerXY_base "m" "m"
6023         test_newerXY_base "m" "c"
6024         test_newerXY_base "c" "a"
6025         test_newerXY_base "c" "m"
6026         test_newerXY_base "c" "c"
6027
6028         [[ -n "$sles_version" ]] &&
6029                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6030
6031         test_newerXY_base "a" "t"
6032         test_newerXY_base "m" "t"
6033         test_newerXY_base "c" "t"
6034
6035         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6036            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6037                 ! btime_supported && echo "btime unsupported" && return 0
6038
6039         test_newerXY_base "b" "b"
6040         test_newerXY_base "b" "t"
6041 }
6042 run_test 56oc "check lfs find -newerXY work"
6043
6044 btime_supported() {
6045         local dir=$DIR/$tdir
6046         local rc
6047
6048         mkdir -p $dir
6049         touch $dir/$tfile
6050         $LFS find $dir -btime -1d -type f
6051         rc=$?
6052         rm -rf $dir
6053         return $rc
6054 }
6055
6056 test_56od() {
6057         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6058                 ! btime_supported && skip "btime unsupported on MDS"
6059
6060         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6061                 ! btime_supported && skip "btime unsupported on clients"
6062
6063         local dir=$DIR/$tdir
6064         local ref=$DIR/$tfile.ref
6065         local negref=$DIR/$tfile.negref
6066
6067         mkdir $dir || error "mkdir $dir failed"
6068         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6069         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6070         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6071         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6072         touch $ref || error "touch $ref failed"
6073         # sleep 3 seconds at least
6074         sleep 3
6075
6076         local before=$(do_facet mds1 date +%s)
6077         local skew=$(($(date +%s) - before + 1))
6078
6079         if (( skew < 0 && skew > -5 )); then
6080                 sleep $((0 - skew + 1))
6081                 skew=0
6082         fi
6083
6084         # Set the dir stripe params to limit files all on MDT0,
6085         # otherwise we need to calc the max clock skew between
6086         # the client and MDTs.
6087         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6088         sleep 2
6089         touch $negref || error "touch $negref failed"
6090
6091         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6092         local nums=$($cmd | wc -l)
6093         local expected=$(((NUMFILES + 1) * NUMDIRS))
6094
6095         [ $nums -eq $expected ] ||
6096                 error "'$cmd' wrong: found $nums, expected $expected"
6097
6098         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6099         nums=$($cmd | wc -l)
6100         expected=$((NUMFILES + 1))
6101         [ $nums -eq $expected ] ||
6102                 error "'$cmd' wrong: found $nums, expected $expected"
6103
6104         [ $skew -lt 0 ] && return
6105
6106         local after=$(do_facet mds1 date +%s)
6107         local age=$((after - before + 1 + skew))
6108
6109         cmd="$LFS find $dir -btime -${age}s -type f"
6110         nums=$($cmd | wc -l)
6111         expected=$(((NUMFILES + 1) * NUMDIRS))
6112
6113         echo "Clock skew between client and server: $skew, age:$age"
6114         [ $nums -eq $expected ] ||
6115                 error "'$cmd' wrong: found $nums, expected $expected"
6116
6117         expected=$(($NUMDIRS + 1))
6118         cmd="$LFS find $dir -btime -${age}s -type d"
6119         nums=$($cmd | wc -l)
6120         [ $nums -eq $expected ] ||
6121                 error "'$cmd' wrong: found $nums, expected $expected"
6122         rm -f $ref $negref || error "Failed to remove $ref $negref"
6123 }
6124 run_test 56od "check lfs find -btime with units"
6125
6126 test_56p() {
6127         [ $RUNAS_ID -eq $UID ] &&
6128                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6129
6130         local dir=$DIR/$tdir
6131
6132         setup_56 $dir $NUMFILES $NUMDIRS
6133         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6134
6135         local expected=$NUMFILES
6136         local cmd="$LFS find -uid $RUNAS_ID $dir"
6137         local nums=$($cmd | wc -l)
6138
6139         [ $nums -eq $expected ] ||
6140                 error "'$cmd' wrong: found $nums, expected $expected"
6141
6142         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6143         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6144         nums=$($cmd | wc -l)
6145         [ $nums -eq $expected ] ||
6146                 error "'$cmd' wrong: found $nums, expected $expected"
6147 }
6148 run_test 56p "check lfs find -uid and ! -uid"
6149
6150 test_56q() {
6151         [ $RUNAS_ID -eq $UID ] &&
6152                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6153
6154         local dir=$DIR/$tdir
6155
6156         setup_56 $dir $NUMFILES $NUMDIRS
6157         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6158
6159         local expected=$NUMFILES
6160         local cmd="$LFS find -gid $RUNAS_GID $dir"
6161         local nums=$($cmd | wc -l)
6162
6163         [ $nums -eq $expected ] ||
6164                 error "'$cmd' wrong: found $nums, expected $expected"
6165
6166         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6167         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6168         nums=$($cmd | wc -l)
6169         [ $nums -eq $expected ] ||
6170                 error "'$cmd' wrong: found $nums, expected $expected"
6171 }
6172 run_test 56q "check lfs find -gid and ! -gid"
6173
6174 test_56r() {
6175         local dir=$DIR/$tdir
6176
6177         setup_56 $dir $NUMFILES $NUMDIRS
6178
6179         local expected=12
6180         local cmd="$LFS find -size 0 -type f -lazy $dir"
6181         local nums=$($cmd | wc -l)
6182
6183         [ $nums -eq $expected ] ||
6184                 error "'$cmd' wrong: found $nums, expected $expected"
6185         cmd="$LFS find -size 0 -type f $dir"
6186         nums=$($cmd | wc -l)
6187         [ $nums -eq $expected ] ||
6188                 error "'$cmd' wrong: found $nums, expected $expected"
6189
6190         expected=0
6191         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6192         nums=$($cmd | wc -l)
6193         [ $nums -eq $expected ] ||
6194                 error "'$cmd' wrong: found $nums, expected $expected"
6195         cmd="$LFS find ! -size 0 -type f $dir"
6196         nums=$($cmd | wc -l)
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199
6200         echo "test" > $dir/$tfile
6201         echo "test2" > $dir/$tfile.2 && sync
6202         expected=1
6203         cmd="$LFS find -size 5 -type f -lazy $dir"
6204         nums=$($cmd | wc -l)
6205         [ $nums -eq $expected ] ||
6206                 error "'$cmd' wrong: found $nums, expected $expected"
6207         cmd="$LFS find -size 5 -type f $dir"
6208         nums=$($cmd | wc -l)
6209         [ $nums -eq $expected ] ||
6210                 error "'$cmd' wrong: found $nums, expected $expected"
6211
6212         expected=1
6213         cmd="$LFS find -size +5 -type f -lazy $dir"
6214         nums=$($cmd | wc -l)
6215         [ $nums -eq $expected ] ||
6216                 error "'$cmd' wrong: found $nums, expected $expected"
6217         cmd="$LFS find -size +5 -type f $dir"
6218         nums=$($cmd | wc -l)
6219         [ $nums -eq $expected ] ||
6220                 error "'$cmd' wrong: found $nums, expected $expected"
6221
6222         expected=2
6223         cmd="$LFS find -size +0 -type f -lazy $dir"
6224         nums=$($cmd | wc -l)
6225         [ $nums -eq $expected ] ||
6226                 error "'$cmd' wrong: found $nums, expected $expected"
6227         cmd="$LFS find -size +0 -type f $dir"
6228         nums=$($cmd | wc -l)
6229         [ $nums -eq $expected ] ||
6230                 error "'$cmd' wrong: found $nums, expected $expected"
6231
6232         expected=2
6233         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6234         nums=$($cmd | wc -l)
6235         [ $nums -eq $expected ] ||
6236                 error "'$cmd' wrong: found $nums, expected $expected"
6237         cmd="$LFS find ! -size -5 -type f $dir"
6238         nums=$($cmd | wc -l)
6239         [ $nums -eq $expected ] ||
6240                 error "'$cmd' wrong: found $nums, expected $expected"
6241
6242         expected=12
6243         cmd="$LFS find -size -5 -type f -lazy $dir"
6244         nums=$($cmd | wc -l)
6245         [ $nums -eq $expected ] ||
6246                 error "'$cmd' wrong: found $nums, expected $expected"
6247         cmd="$LFS find -size -5 -type f $dir"
6248         nums=$($cmd | wc -l)
6249         [ $nums -eq $expected ] ||
6250                 error "'$cmd' wrong: found $nums, expected $expected"
6251 }
6252 run_test 56r "check lfs find -size works"
6253
6254 test_56ra_sub() {
6255         local expected=$1
6256         local glimpses=$2
6257         local cmd="$3"
6258
6259         cancel_lru_locks $OSC
6260
6261         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6262         local nums=$($cmd | wc -l)
6263
6264         [ $nums -eq $expected ] ||
6265                 error "'$cmd' wrong: found $nums, expected $expected"
6266
6267         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6268
6269         if (( rpcs_before + glimpses != rpcs_after )); then
6270                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6271                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6272
6273                 if [[ $glimpses == 0 ]]; then
6274                         error "'$cmd' should not send glimpse RPCs to OST"
6275                 else
6276                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6277                 fi
6278         fi
6279 }
6280
6281 test_56ra() {
6282         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6283                 skip "MDS < 2.12.58 doesn't return LSOM data"
6284         local dir=$DIR/$tdir
6285         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6286
6287         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6288
6289         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6290         $LCTL set_param -n llite.*.statahead_agl=0
6291         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6292
6293         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6294         # open and close all files to ensure LSOM is updated
6295         cancel_lru_locks $OSC
6296         find $dir -type f | xargs cat > /dev/null
6297
6298         #   expect_found  glimpse_rpcs  command_to_run
6299         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6300         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6301         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6302         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6303
6304         echo "test" > $dir/$tfile
6305         echo "test2" > $dir/$tfile.2 && sync
6306         cancel_lru_locks $OSC
6307         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6308
6309         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6310         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6311         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6312         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6313
6314         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6315         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6316         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6317         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6318         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6319         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6320 }
6321 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6322
6323 test_56rb() {
6324         local dir=$DIR/$tdir
6325         local tmp=$TMP/$tfile.log
6326         local mdt_idx;
6327
6328         test_mkdir -p $dir || error "failed to mkdir $dir"
6329         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6330                 error "failed to setstripe $dir/$tfile"
6331         mdt_idx=$($LFS getdirstripe -i $dir)
6332         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6333
6334         stack_trap "rm -f $tmp" EXIT
6335         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6336         ! grep -q obd_uuid $tmp ||
6337                 error "failed to find --size +100K --ost 0 $dir"
6338         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6339         ! grep -q obd_uuid $tmp ||
6340                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6341 }
6342 run_test 56rb "check lfs find --size --ost/--mdt works"
6343
6344 test_56s() { # LU-611 #LU-9369
6345         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6346
6347         local dir=$DIR/$tdir
6348         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6349
6350         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6351         for i in $(seq $NUMDIRS); do
6352                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6353         done
6354
6355         local expected=$NUMDIRS
6356         local cmd="$LFS find -c $OSTCOUNT $dir"
6357         local nums=$($cmd | wc -l)
6358
6359         [ $nums -eq $expected ] || {
6360                 $LFS getstripe -R $dir
6361                 error "'$cmd' wrong: found $nums, expected $expected"
6362         }
6363
6364         expected=$((NUMDIRS + onestripe))
6365         cmd="$LFS find -stripe-count +0 -type f $dir"
6366         nums=$($cmd | wc -l)
6367         [ $nums -eq $expected ] || {
6368                 $LFS getstripe -R $dir
6369                 error "'$cmd' wrong: found $nums, expected $expected"
6370         }
6371
6372         expected=$onestripe
6373         cmd="$LFS find -stripe-count 1 -type f $dir"
6374         nums=$($cmd | wc -l)
6375         [ $nums -eq $expected ] || {
6376                 $LFS getstripe -R $dir
6377                 error "'$cmd' wrong: found $nums, expected $expected"
6378         }
6379
6380         cmd="$LFS find -stripe-count -2 -type f $dir"
6381         nums=$($cmd | wc -l)
6382         [ $nums -eq $expected ] || {
6383                 $LFS getstripe -R $dir
6384                 error "'$cmd' wrong: found $nums, expected $expected"
6385         }
6386
6387         expected=0
6388         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6389         nums=$($cmd | wc -l)
6390         [ $nums -eq $expected ] || {
6391                 $LFS getstripe -R $dir
6392                 error "'$cmd' wrong: found $nums, expected $expected"
6393         }
6394 }
6395 run_test 56s "check lfs find -stripe-count works"
6396
6397 test_56t() { # LU-611 #LU-9369
6398         local dir=$DIR/$tdir
6399
6400         setup_56 $dir 0 $NUMDIRS
6401         for i in $(seq $NUMDIRS); do
6402                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6403         done
6404
6405         local expected=$NUMDIRS
6406         local cmd="$LFS find -S 8M $dir"
6407         local nums=$($cmd | wc -l)
6408
6409         [ $nums -eq $expected ] || {
6410                 $LFS getstripe -R $dir
6411                 error "'$cmd' wrong: found $nums, expected $expected"
6412         }
6413         rm -rf $dir
6414
6415         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6416
6417         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6418
6419         expected=$(((NUMDIRS + 1) * NUMFILES))
6420         cmd="$LFS find -stripe-size 512k -type f $dir"
6421         nums=$($cmd | wc -l)
6422         [ $nums -eq $expected ] ||
6423                 error "'$cmd' wrong: found $nums, expected $expected"
6424
6425         cmd="$LFS find -stripe-size +320k -type f $dir"
6426         nums=$($cmd | wc -l)
6427         [ $nums -eq $expected ] ||
6428                 error "'$cmd' wrong: found $nums, expected $expected"
6429
6430         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6431         cmd="$LFS find -stripe-size +200k -type f $dir"
6432         nums=$($cmd | wc -l)
6433         [ $nums -eq $expected ] ||
6434                 error "'$cmd' wrong: found $nums, expected $expected"
6435
6436         cmd="$LFS find -stripe-size -640k -type f $dir"
6437         nums=$($cmd | wc -l)
6438         [ $nums -eq $expected ] ||
6439                 error "'$cmd' wrong: found $nums, expected $expected"
6440
6441         expected=4
6442         cmd="$LFS find -stripe-size 256k -type f $dir"
6443         nums=$($cmd | wc -l)
6444         [ $nums -eq $expected ] ||
6445                 error "'$cmd' wrong: found $nums, expected $expected"
6446
6447         cmd="$LFS find -stripe-size -320k -type f $dir"
6448         nums=$($cmd | wc -l)
6449         [ $nums -eq $expected ] ||
6450                 error "'$cmd' wrong: found $nums, expected $expected"
6451
6452         expected=0
6453         cmd="$LFS find -stripe-size 1024k -type f $dir"
6454         nums=$($cmd | wc -l)
6455         [ $nums -eq $expected ] ||
6456                 error "'$cmd' wrong: found $nums, expected $expected"
6457 }
6458 run_test 56t "check lfs find -stripe-size works"
6459
6460 test_56u() { # LU-611
6461         local dir=$DIR/$tdir
6462
6463         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6464
6465         if [[ $OSTCOUNT -gt 1 ]]; then
6466                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6467                 onestripe=4
6468         else
6469                 onestripe=0
6470         fi
6471
6472         local expected=$(((NUMDIRS + 1) * NUMFILES))
6473         local cmd="$LFS find -stripe-index 0 -type f $dir"
6474         local nums=$($cmd | wc -l)
6475
6476         [ $nums -eq $expected ] ||
6477                 error "'$cmd' wrong: found $nums, expected $expected"
6478
6479         expected=$onestripe
6480         cmd="$LFS find -stripe-index 1 -type f $dir"
6481         nums=$($cmd | wc -l)
6482         [ $nums -eq $expected ] ||
6483                 error "'$cmd' wrong: found $nums, expected $expected"
6484
6485         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6486         nums=$($cmd | wc -l)
6487         [ $nums -eq $expected ] ||
6488                 error "'$cmd' wrong: found $nums, expected $expected"
6489
6490         expected=0
6491         # This should produce an error and not return any files
6492         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6493         nums=$($cmd 2>/dev/null | wc -l)
6494         [ $nums -eq $expected ] ||
6495                 error "'$cmd' wrong: found $nums, expected $expected"
6496
6497         if [[ $OSTCOUNT -gt 1 ]]; then
6498                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6499                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6500                 nums=$($cmd | wc -l)
6501                 [ $nums -eq $expected ] ||
6502                         error "'$cmd' wrong: found $nums, expected $expected"
6503         fi
6504 }
6505 run_test 56u "check lfs find -stripe-index works"
6506
6507 test_56v() {
6508         local mdt_idx=0
6509         local dir=$DIR/$tdir
6510
6511         setup_56 $dir $NUMFILES $NUMDIRS
6512
6513         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6514         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6515
6516         for file in $($LFS find -m $UUID $dir); do
6517                 file_midx=$($LFS getstripe -m $file)
6518                 [ $file_midx -eq $mdt_idx ] ||
6519                         error "lfs find -m $UUID != getstripe -m $file_midx"
6520         done
6521 }
6522 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6523
6524 test_56w() {
6525         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6527
6528         local dir=$DIR/$tdir
6529
6530         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6531
6532         local stripe_size=$($LFS getstripe -S -d $dir) ||
6533                 error "$LFS getstripe -S -d $dir failed"
6534         stripe_size=${stripe_size%% *}
6535
6536         local file_size=$((stripe_size * OSTCOUNT))
6537         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6538         local required_space=$((file_num * file_size))
6539         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6540                            head -n1)
6541         [[ $free_space -le $((required_space / 1024)) ]] &&
6542                 skip_env "need $required_space, have $free_space kbytes"
6543
6544         local dd_bs=65536
6545         local dd_count=$((file_size / dd_bs))
6546
6547         # write data into the files
6548         local i
6549         local j
6550         local file
6551
6552         for i in $(seq $NUMFILES); do
6553                 file=$dir/file$i
6554                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6555                         error "write data into $file failed"
6556         done
6557         for i in $(seq $NUMDIRS); do
6558                 for j in $(seq $NUMFILES); do
6559                         file=$dir/dir$i/file$j
6560                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6561                                 error "write data into $file failed"
6562                 done
6563         done
6564
6565         # $LFS_MIGRATE will fail if hard link migration is unsupported
6566         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6567                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6568                         error "creating links to $dir/dir1/file1 failed"
6569         fi
6570
6571         local expected=-1
6572
6573         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6574
6575         # lfs_migrate file
6576         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6577
6578         echo "$cmd"
6579         eval $cmd || error "$cmd failed"
6580
6581         check_stripe_count $dir/file1 $expected
6582
6583         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6584         then
6585                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6586                 # OST 1 if it is on OST 0. This file is small enough to
6587                 # be on only one stripe.
6588                 file=$dir/migr_1_ost
6589                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6590                         error "write data into $file failed"
6591                 local obdidx=$($LFS getstripe -i $file)
6592                 local oldmd5=$(md5sum $file)
6593                 local newobdidx=0
6594
6595                 [[ $obdidx -eq 0 ]] && newobdidx=1
6596                 cmd="$LFS migrate -i $newobdidx $file"
6597                 echo $cmd
6598                 eval $cmd || error "$cmd failed"
6599
6600                 local realobdix=$($LFS getstripe -i $file)
6601                 local newmd5=$(md5sum $file)
6602
6603                 [[ $newobdidx -ne $realobdix ]] &&
6604                         error "new OST is different (was=$obdidx, "\
6605                               "wanted=$newobdidx, got=$realobdix)"
6606                 [[ "$oldmd5" != "$newmd5" ]] &&
6607                         error "md5sum differ: $oldmd5, $newmd5"
6608         fi
6609
6610         # lfs_migrate dir
6611         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6612         echo "$cmd"
6613         eval $cmd || error "$cmd failed"
6614
6615         for j in $(seq $NUMFILES); do
6616                 check_stripe_count $dir/dir1/file$j $expected
6617         done
6618
6619         # lfs_migrate works with lfs find
6620         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6621              $LFS_MIGRATE -y -c $expected"
6622         echo "$cmd"
6623         eval $cmd || error "$cmd failed"
6624
6625         for i in $(seq 2 $NUMFILES); do
6626                 check_stripe_count $dir/file$i $expected
6627         done
6628         for i in $(seq 2 $NUMDIRS); do
6629                 for j in $(seq $NUMFILES); do
6630                 check_stripe_count $dir/dir$i/file$j $expected
6631                 done
6632         done
6633 }
6634 run_test 56w "check lfs_migrate -c stripe_count works"
6635
6636 test_56wb() {
6637         local file1=$DIR/$tdir/file1
6638         local create_pool=false
6639         local initial_pool=$($LFS getstripe -p $DIR)
6640         local pool_list=()
6641         local pool=""
6642
6643         echo -n "Creating test dir..."
6644         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6645         echo "done."
6646
6647         echo -n "Creating test file..."
6648         touch $file1 || error "cannot create file"
6649         echo "done."
6650
6651         echo -n "Detecting existing pools..."
6652         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6653
6654         if [ ${#pool_list[@]} -gt 0 ]; then
6655                 echo "${pool_list[@]}"
6656                 for thispool in "${pool_list[@]}"; do
6657                         if [[ -z "$initial_pool" ||
6658                               "$initial_pool" != "$thispool" ]]; then
6659                                 pool="$thispool"
6660                                 echo "Using existing pool '$pool'"
6661                                 break
6662                         fi
6663                 done
6664         else
6665                 echo "none detected."
6666         fi
6667         if [ -z "$pool" ]; then
6668                 pool=${POOL:-testpool}
6669                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6670                 echo -n "Creating pool '$pool'..."
6671                 create_pool=true
6672                 pool_add $pool &> /dev/null ||
6673                         error "pool_add failed"
6674                 echo "done."
6675
6676                 echo -n "Adding target to pool..."
6677                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6678                         error "pool_add_targets failed"
6679                 echo "done."
6680         fi
6681
6682         echo -n "Setting pool using -p option..."
6683         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6684                 error "migrate failed rc = $?"
6685         echo "done."
6686
6687         echo -n "Verifying test file is in pool after migrating..."
6688         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6689                 error "file was not migrated to pool $pool"
6690         echo "done."
6691
6692         echo -n "Removing test file from pool '$pool'..."
6693         # "lfs migrate $file" won't remove the file from the pool
6694         # until some striping information is changed.
6695         $LFS migrate -c 1 $file1 &> /dev/null ||
6696                 error "cannot remove from pool"
6697         [ "$($LFS getstripe -p $file1)" ] &&
6698                 error "pool still set"
6699         echo "done."
6700
6701         echo -n "Setting pool using --pool option..."
6702         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6703                 error "migrate failed rc = $?"
6704         echo "done."
6705
6706         # Clean up
6707         rm -f $file1
6708         if $create_pool; then
6709                 destroy_test_pools 2> /dev/null ||
6710                         error "destroy test pools failed"
6711         fi
6712 }
6713 run_test 56wb "check lfs_migrate pool support"
6714
6715 test_56wc() {
6716         local file1="$DIR/$tdir/file1"
6717         local parent_ssize
6718         local parent_scount
6719         local cur_ssize
6720         local cur_scount
6721         local orig_ssize
6722
6723         echo -n "Creating test dir..."
6724         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6725         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6726                 error "cannot set stripe by '-S 1M -c 1'"
6727         echo "done"
6728
6729         echo -n "Setting initial stripe for test file..."
6730         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6731                 error "cannot set stripe"
6732         cur_ssize=$($LFS getstripe -S "$file1")
6733         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6734         echo "done."
6735
6736         # File currently set to -S 512K -c 1
6737
6738         # Ensure -c and -S options are rejected when -R is set
6739         echo -n "Verifying incompatible options are detected..."
6740         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6741                 error "incompatible -c and -R options not detected"
6742         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6743                 error "incompatible -S and -R options not detected"
6744         echo "done."
6745
6746         # Ensure unrecognized options are passed through to 'lfs migrate'
6747         echo -n "Verifying -S option is passed through to lfs migrate..."
6748         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6749                 error "migration failed"
6750         cur_ssize=$($LFS getstripe -S "$file1")
6751         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6752         echo "done."
6753
6754         # File currently set to -S 1M -c 1
6755
6756         # Ensure long options are supported
6757         echo -n "Verifying long options supported..."
6758         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6759                 error "long option without argument not supported"
6760         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6761                 error "long option with argument not supported"
6762         cur_ssize=$($LFS getstripe -S "$file1")
6763         [ $cur_ssize -eq 524288 ] ||
6764                 error "migrate --stripe-size $cur_ssize != 524288"
6765         echo "done."
6766
6767         # File currently set to -S 512K -c 1
6768
6769         if [ "$OSTCOUNT" -gt 1 ]; then
6770                 echo -n "Verifying explicit stripe count can be set..."
6771                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6772                         error "migrate failed"
6773                 cur_scount=$($LFS getstripe -c "$file1")
6774                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6775                 echo "done."
6776         fi
6777
6778         # File currently set to -S 512K -c 1 or -S 512K -c 2
6779
6780         # Ensure parent striping is used if -R is set, and no stripe
6781         # count or size is specified
6782         echo -n "Setting stripe for parent directory..."
6783         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6784                 error "cannot set stripe '-S 2M -c 1'"
6785         echo "done."
6786
6787         echo -n "Verifying restripe option uses parent stripe settings..."
6788         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6789         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6790         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6791                 error "migrate failed"
6792         cur_ssize=$($LFS getstripe -S "$file1")
6793         [ $cur_ssize -eq $parent_ssize ] ||
6794                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6795         cur_scount=$($LFS getstripe -c "$file1")
6796         [ $cur_scount -eq $parent_scount ] ||
6797                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6798         echo "done."
6799
6800         # File currently set to -S 1M -c 1
6801
6802         # Ensure striping is preserved if -R is not set, and no stripe
6803         # count or size is specified
6804         echo -n "Verifying striping size preserved when not specified..."
6805         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6806         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6807                 error "cannot set stripe on parent directory"
6808         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6809                 error "migrate failed"
6810         cur_ssize=$($LFS getstripe -S "$file1")
6811         [ $cur_ssize -eq $orig_ssize ] ||
6812                 error "migrate by default $cur_ssize != $orig_ssize"
6813         echo "done."
6814
6815         # Ensure file name properly detected when final option has no argument
6816         echo -n "Verifying file name properly detected..."
6817         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6818                 error "file name interpreted as option argument"
6819         echo "done."
6820
6821         # Clean up
6822         rm -f "$file1"
6823 }
6824 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6825
6826 test_56wd() {
6827         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6828
6829         local file1=$DIR/$tdir/file1
6830
6831         echo -n "Creating test dir..."
6832         test_mkdir $DIR/$tdir || error "cannot create dir"
6833         echo "done."
6834
6835         echo -n "Creating test file..."
6836         touch $file1
6837         echo "done."
6838
6839         # Ensure 'lfs migrate' will fail by using a non-existent option,
6840         # and make sure rsync is not called to recover
6841         echo -n "Make sure --no-rsync option works..."
6842         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6843                 grep -q 'refusing to fall back to rsync' ||
6844                 error "rsync was called with --no-rsync set"
6845         echo "done."
6846
6847         # Ensure rsync is called without trying 'lfs migrate' first
6848         echo -n "Make sure --rsync option works..."
6849         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6850                 grep -q 'falling back to rsync' &&
6851                 error "lfs migrate was called with --rsync set"
6852         echo "done."
6853
6854         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6855         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6856                 grep -q 'at the same time' ||
6857                 error "--rsync and --no-rsync accepted concurrently"
6858         echo "done."
6859
6860         # Clean up
6861         rm -f $file1
6862 }
6863 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6864
6865 test_56we() {
6866         local td=$DIR/$tdir
6867         local tf=$td/$tfile
6868
6869         test_mkdir $td || error "cannot create $td"
6870         touch $tf || error "cannot touch $tf"
6871
6872         echo -n "Make sure --non-direct|-D works..."
6873         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6874                 grep -q "lfs migrate --non-direct" ||
6875                 error "--non-direct option cannot work correctly"
6876         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6877                 grep -q "lfs migrate -D" ||
6878                 error "-D option cannot work correctly"
6879         echo "done."
6880 }
6881 run_test 56we "check lfs_migrate --non-direct|-D support"
6882
6883 test_56x() {
6884         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6885         check_swap_layouts_support
6886
6887         local dir=$DIR/$tdir
6888         local ref1=/etc/passwd
6889         local file1=$dir/file1
6890
6891         test_mkdir $dir || error "creating dir $dir"
6892         $LFS setstripe -c 2 $file1
6893         cp $ref1 $file1
6894         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6895         stripe=$($LFS getstripe -c $file1)
6896         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6897         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6898
6899         # clean up
6900         rm -f $file1
6901 }
6902 run_test 56x "lfs migration support"
6903
6904 test_56xa() {
6905         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6906         check_swap_layouts_support
6907
6908         local dir=$DIR/$tdir/$testnum
6909
6910         test_mkdir -p $dir
6911
6912         local ref1=/etc/passwd
6913         local file1=$dir/file1
6914
6915         $LFS setstripe -c 2 $file1
6916         cp $ref1 $file1
6917         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6918
6919         local stripe=$($LFS getstripe -c $file1)
6920
6921         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6922         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6923
6924         # clean up
6925         rm -f $file1
6926 }
6927 run_test 56xa "lfs migration --block support"
6928
6929 check_migrate_links() {
6930         local dir="$1"
6931         local file1="$dir/file1"
6932         local begin="$2"
6933         local count="$3"
6934         local runas="$4"
6935         local total_count=$(($begin + $count - 1))
6936         local symlink_count=10
6937         local uniq_count=10
6938
6939         if [ ! -f "$file1" ]; then
6940                 echo -n "creating initial file..."
6941                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6942                         error "cannot setstripe initial file"
6943                 echo "done"
6944
6945                 echo -n "creating symlinks..."
6946                 for s in $(seq 1 $symlink_count); do
6947                         ln -s "$file1" "$dir/slink$s" ||
6948                                 error "cannot create symlinks"
6949                 done
6950                 echo "done"
6951
6952                 echo -n "creating nonlinked files..."
6953                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6954                         error "cannot create nonlinked files"
6955                 echo "done"
6956         fi
6957
6958         # create hard links
6959         if [ ! -f "$dir/file$total_count" ]; then
6960                 echo -n "creating hard links $begin:$total_count..."
6961                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6962                         /dev/null || error "cannot create hard links"
6963                 echo "done"
6964         fi
6965
6966         echo -n "checking number of hard links listed in xattrs..."
6967         local fid=$($LFS getstripe -F "$file1")
6968         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6969
6970         echo "${#paths[*]}"
6971         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6972                         skip "hard link list has unexpected size, skipping test"
6973         fi
6974         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6975                         error "link names should exceed xattrs size"
6976         fi
6977
6978         echo -n "migrating files..."
6979         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6980         local rc=$?
6981         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6982         echo "done"
6983
6984         # make sure all links have been properly migrated
6985         echo -n "verifying files..."
6986         fid=$($LFS getstripe -F "$file1") ||
6987                 error "cannot get fid for file $file1"
6988         for i in $(seq 2 $total_count); do
6989                 local fid2=$($LFS getstripe -F $dir/file$i)
6990
6991                 [ "$fid2" == "$fid" ] ||
6992                         error "migrated hard link has mismatched FID"
6993         done
6994
6995         # make sure hard links were properly detected, and migration was
6996         # performed only once for the entire link set; nonlinked files should
6997         # also be migrated
6998         local actual=$(grep -c 'done' <<< "$migrate_out")
6999         local expected=$(($uniq_count + 1))
7000
7001         [ "$actual" -eq  "$expected" ] ||
7002                 error "hard links individually migrated ($actual != $expected)"
7003
7004         # make sure the correct number of hard links are present
7005         local hardlinks=$(stat -c '%h' "$file1")
7006
7007         [ $hardlinks -eq $total_count ] ||
7008                 error "num hard links $hardlinks != $total_count"
7009         echo "done"
7010
7011         return 0
7012 }
7013
7014 test_56xb() {
7015         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7016                 skip "Need MDS version at least 2.10.55"
7017
7018         local dir="$DIR/$tdir"
7019
7020         test_mkdir "$dir" || error "cannot create dir $dir"
7021
7022         echo "testing lfs migrate mode when all links fit within xattrs"
7023         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7024
7025         echo "testing rsync mode when all links fit within xattrs"
7026         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7027
7028         echo "testing lfs migrate mode when all links do not fit within xattrs"
7029         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7030
7031         echo "testing rsync mode when all links do not fit within xattrs"
7032         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7033
7034         chown -R $RUNAS_ID $dir
7035         echo "testing non-root lfs migrate mode when not all links are in xattr"
7036         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7037
7038         # clean up
7039         rm -rf $dir
7040 }
7041 run_test 56xb "lfs migration hard link support"
7042
7043 test_56xc() {
7044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7045
7046         local dir="$DIR/$tdir"
7047
7048         test_mkdir "$dir" || error "cannot create dir $dir"
7049
7050         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7051         echo -n "Setting initial stripe for 20MB test file..."
7052         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7053                 error "cannot setstripe 20MB file"
7054         echo "done"
7055         echo -n "Sizing 20MB test file..."
7056         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7057         echo "done"
7058         echo -n "Verifying small file autostripe count is 1..."
7059         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7060                 error "cannot migrate 20MB file"
7061         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7062                 error "cannot get stripe for $dir/20mb"
7063         [ $stripe_count -eq 1 ] ||
7064                 error "unexpected stripe count $stripe_count for 20MB file"
7065         rm -f "$dir/20mb"
7066         echo "done"
7067
7068         # Test 2: File is small enough to fit within the available space on
7069         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7070         # have at least an additional 1KB for each desired stripe for test 3
7071         echo -n "Setting stripe for 1GB test file..."
7072         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7073         echo "done"
7074         echo -n "Sizing 1GB test file..."
7075         # File size is 1GB + 3KB
7076         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7077         echo "done"
7078
7079         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7080         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7081         if (( avail > 524288 * OSTCOUNT )); then
7082                 echo -n "Migrating 1GB file..."
7083                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7084                         error "cannot migrate 1GB file"
7085                 echo "done"
7086                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7087                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7088                         error "cannot getstripe for 1GB file"
7089                 [ $stripe_count -eq 2 ] ||
7090                         error "unexpected stripe count $stripe_count != 2"
7091                 echo "done"
7092         fi
7093
7094         # Test 3: File is too large to fit within the available space on
7095         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7096         if [ $OSTCOUNT -ge 3 ]; then
7097                 # The required available space is calculated as
7098                 # file size (1GB + 3KB) / OST count (3).
7099                 local kb_per_ost=349526
7100
7101                 echo -n "Migrating 1GB file with limit..."
7102                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7103                         error "cannot migrate 1GB file with limit"
7104                 echo "done"
7105
7106                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7107                 echo -n "Verifying 1GB autostripe count with limited space..."
7108                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7109                         error "unexpected stripe count $stripe_count (min 3)"
7110                 echo "done"
7111         fi
7112
7113         # clean up
7114         rm -rf $dir
7115 }
7116 run_test 56xc "lfs migration autostripe"
7117
7118 test_56xd() {
7119         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7120
7121         local dir=$DIR/$tdir
7122         local f_mgrt=$dir/$tfile.mgrt
7123         local f_yaml=$dir/$tfile.yaml
7124         local f_copy=$dir/$tfile.copy
7125         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7126         local layout_copy="-c 2 -S 2M -i 1"
7127         local yamlfile=$dir/yamlfile
7128         local layout_before;
7129         local layout_after;
7130
7131         test_mkdir "$dir" || error "cannot create dir $dir"
7132         $LFS setstripe $layout_yaml $f_yaml ||
7133                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7134         $LFS getstripe --yaml $f_yaml > $yamlfile
7135         $LFS setstripe $layout_copy $f_copy ||
7136                 error "cannot setstripe $f_copy with layout $layout_copy"
7137         touch $f_mgrt
7138         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7139
7140         # 1. test option --yaml
7141         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7142                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7143         layout_before=$(get_layout_param $f_yaml)
7144         layout_after=$(get_layout_param $f_mgrt)
7145         [ "$layout_after" == "$layout_before" ] ||
7146                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7147
7148         # 2. test option --copy
7149         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7150                 error "cannot migrate $f_mgrt with --copy $f_copy"
7151         layout_before=$(get_layout_param $f_copy)
7152         layout_after=$(get_layout_param $f_mgrt)
7153         [ "$layout_after" == "$layout_before" ] ||
7154                 error "lfs_migrate --copy: $layout_after != $layout_before"
7155 }
7156 run_test 56xd "check lfs_migrate --yaml and --copy support"
7157
7158 test_56xe() {
7159         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7160
7161         local dir=$DIR/$tdir
7162         local f_comp=$dir/$tfile
7163         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7164         local layout_before=""
7165         local layout_after=""
7166
7167         test_mkdir "$dir" || error "cannot create dir $dir"
7168         $LFS setstripe $layout $f_comp ||
7169                 error "cannot setstripe $f_comp with layout $layout"
7170         layout_before=$(get_layout_param $f_comp)
7171         dd if=/dev/zero of=$f_comp bs=1M count=4
7172
7173         # 1. migrate a comp layout file by lfs_migrate
7174         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7175         layout_after=$(get_layout_param $f_comp)
7176         [ "$layout_before" == "$layout_after" ] ||
7177                 error "lfs_migrate: $layout_before != $layout_after"
7178
7179         # 2. migrate a comp layout file by lfs migrate
7180         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7181         layout_after=$(get_layout_param $f_comp)
7182         [ "$layout_before" == "$layout_after" ] ||
7183                 error "lfs migrate: $layout_before != $layout_after"
7184 }
7185 run_test 56xe "migrate a composite layout file"
7186
7187 test_56xf() {
7188         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7189
7190         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7191                 skip "Need server version at least 2.13.53"
7192
7193         local dir=$DIR/$tdir
7194         local f_comp=$dir/$tfile
7195         local layout="-E 1M -c1 -E -1 -c2"
7196         local fid_before=""
7197         local fid_after=""
7198
7199         test_mkdir "$dir" || error "cannot create dir $dir"
7200         $LFS setstripe $layout $f_comp ||
7201                 error "cannot setstripe $f_comp with layout $layout"
7202         fid_before=$($LFS getstripe --fid $f_comp)
7203         dd if=/dev/zero of=$f_comp bs=1M count=4
7204
7205         # 1. migrate a comp layout file to a comp layout
7206         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7207         fid_after=$($LFS getstripe --fid $f_comp)
7208         [ "$fid_before" == "$fid_after" ] ||
7209                 error "comp-to-comp migrate: $fid_before != $fid_after"
7210
7211         # 2. migrate a comp layout file to a plain layout
7212         $LFS migrate -c2 $f_comp ||
7213                 error "cannot migrate $f_comp by lfs migrate"
7214         fid_after=$($LFS getstripe --fid $f_comp)
7215         [ "$fid_before" == "$fid_after" ] ||
7216                 error "comp-to-plain migrate: $fid_before != $fid_after"
7217
7218         # 3. migrate a plain layout file to a comp layout
7219         $LFS migrate $layout $f_comp ||
7220                 error "cannot migrate $f_comp by lfs migrate"
7221         fid_after=$($LFS getstripe --fid $f_comp)
7222         [ "$fid_before" == "$fid_after" ] ||
7223                 error "plain-to-comp migrate: $fid_before != $fid_after"
7224 }
7225 run_test 56xf "FID is not lost during migration of a composite layout file"
7226
7227 test_56y() {
7228         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7229                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7230
7231         local res=""
7232         local dir=$DIR/$tdir
7233         local f1=$dir/file1
7234         local f2=$dir/file2
7235
7236         test_mkdir -p $dir || error "creating dir $dir"
7237         touch $f1 || error "creating std file $f1"
7238         $MULTIOP $f2 H2c || error "creating released file $f2"
7239
7240         # a directory can be raid0, so ask only for files
7241         res=$($LFS find $dir -L raid0 -type f | wc -l)
7242         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7243
7244         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7245         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7246
7247         # only files can be released, so no need to force file search
7248         res=$($LFS find $dir -L released)
7249         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7250
7251         res=$($LFS find $dir -type f \! -L released)
7252         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7253 }
7254 run_test 56y "lfs find -L raid0|released"
7255
7256 test_56z() { # LU-4824
7257         # This checks to make sure 'lfs find' continues after errors
7258         # There are two classes of errors that should be caught:
7259         # - If multiple paths are provided, all should be searched even if one
7260         #   errors out
7261         # - If errors are encountered during the search, it should not terminate
7262         #   early
7263         local dir=$DIR/$tdir
7264         local i
7265
7266         test_mkdir $dir
7267         for i in d{0..9}; do
7268                 test_mkdir $dir/$i
7269                 touch $dir/$i/$tfile
7270         done
7271         $LFS find $DIR/non_existent_dir $dir &&
7272                 error "$LFS find did not return an error"
7273         # Make a directory unsearchable. This should NOT be the last entry in
7274         # directory order.  Arbitrarily pick the 6th entry
7275         chmod 700 $($LFS find $dir -type d | sed '6!d')
7276
7277         $RUNAS $LFS find $DIR/non_existent $dir
7278         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7279
7280         # The user should be able to see 10 directories and 9 files
7281         (( count == 19 )) ||
7282                 error "$LFS find found $count != 19 entries after error"
7283 }
7284 run_test 56z "lfs find should continue after an error"
7285
7286 test_56aa() { # LU-5937
7287         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7288
7289         local dir=$DIR/$tdir
7290
7291         mkdir $dir
7292         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7293
7294         createmany -o $dir/striped_dir/${tfile}- 1024
7295         local dirs=$($LFS find --size +8k $dir/)
7296
7297         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7298 }
7299 run_test 56aa "lfs find --size under striped dir"
7300
7301 test_56ab() { # LU-10705
7302         test_mkdir $DIR/$tdir
7303         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7304         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7305         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7306         # Flush writes to ensure valid blocks.  Need to be more thorough for
7307         # ZFS, since blocks are not allocated/returned to client immediately.
7308         sync_all_data
7309         wait_zfs_commit ost1 2
7310         cancel_lru_locks osc
7311         ls -ls $DIR/$tdir
7312
7313         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7314
7315         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7316
7317         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7318         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7319
7320         rm -f $DIR/$tdir/$tfile.[123]
7321 }
7322 run_test 56ab "lfs find --blocks"
7323
7324 test_56ba() {
7325         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7326                 skip "Need MDS version at least 2.10.50"
7327
7328         # Create composite files with one component
7329         local dir=$DIR/$tdir
7330
7331         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7332         # Create composite files with three components
7333         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7334         # Create non-composite files
7335         createmany -o $dir/${tfile}- 10
7336
7337         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7338
7339         [[ $nfiles == 10 ]] ||
7340                 error "lfs find -E 1M found $nfiles != 10 files"
7341
7342         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7343         [[ $nfiles == 25 ]] ||
7344                 error "lfs find ! -E 1M found $nfiles != 25 files"
7345
7346         # All files have a component that starts at 0
7347         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7348         [[ $nfiles == 35 ]] ||
7349                 error "lfs find --component-start 0 - $nfiles != 35 files"
7350
7351         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7352         [[ $nfiles == 15 ]] ||
7353                 error "lfs find --component-start 2M - $nfiles != 15 files"
7354
7355         # All files created here have a componenet that does not starts at 2M
7356         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7357         [[ $nfiles == 35 ]] ||
7358                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7359
7360         # Find files with a specified number of components
7361         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7362         [[ $nfiles == 15 ]] ||
7363                 error "lfs find --component-count 3 - $nfiles != 15 files"
7364
7365         # Remember non-composite files have a component count of zero
7366         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7367         [[ $nfiles == 10 ]] ||
7368                 error "lfs find --component-count 0 - $nfiles != 10 files"
7369
7370         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7371         [[ $nfiles == 20 ]] ||
7372                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7373
7374         # All files have a flag called "init"
7375         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7376         [[ $nfiles == 35 ]] ||
7377                 error "lfs find --component-flags init - $nfiles != 35 files"
7378
7379         # Multi-component files will have a component not initialized
7380         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7381         [[ $nfiles == 15 ]] ||
7382                 error "lfs find !--component-flags init - $nfiles != 15 files"
7383
7384         rm -rf $dir
7385
7386 }
7387 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7388
7389 test_56ca() {
7390         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7391                 skip "Need MDS version at least 2.10.57"
7392
7393         local td=$DIR/$tdir
7394         local tf=$td/$tfile
7395         local dir
7396         local nfiles
7397         local cmd
7398         local i
7399         local j
7400
7401         # create mirrored directories and mirrored files
7402         mkdir $td || error "mkdir $td failed"
7403         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7404         createmany -o $tf- 10 || error "create $tf- failed"
7405
7406         for i in $(seq 2); do
7407                 dir=$td/dir$i
7408                 mkdir $dir || error "mkdir $dir failed"
7409                 $LFS mirror create -N$((3 + i)) $dir ||
7410                         error "create mirrored dir $dir failed"
7411                 createmany -o $dir/$tfile- 10 ||
7412                         error "create $dir/$tfile- failed"
7413         done
7414
7415         # change the states of some mirrored files
7416         echo foo > $tf-6
7417         for i in $(seq 2); do
7418                 dir=$td/dir$i
7419                 for j in $(seq 4 9); do
7420                         echo foo > $dir/$tfile-$j
7421                 done
7422         done
7423
7424         # find mirrored files with specific mirror count
7425         cmd="$LFS find --mirror-count 3 --type f $td"
7426         nfiles=$($cmd | wc -l)
7427         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7428
7429         cmd="$LFS find ! --mirror-count 3 --type f $td"
7430         nfiles=$($cmd | wc -l)
7431         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7432
7433         cmd="$LFS find --mirror-count +2 --type f $td"
7434         nfiles=$($cmd | wc -l)
7435         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7436
7437         cmd="$LFS find --mirror-count -6 --type f $td"
7438         nfiles=$($cmd | wc -l)
7439         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7440
7441         # find mirrored files with specific file state
7442         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7443         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7444
7445         cmd="$LFS find --mirror-state=ro --type f $td"
7446         nfiles=$($cmd | wc -l)
7447         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7448
7449         cmd="$LFS find ! --mirror-state=ro --type f $td"
7450         nfiles=$($cmd | wc -l)
7451         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7452
7453         cmd="$LFS find --mirror-state=wp --type f $td"
7454         nfiles=$($cmd | wc -l)
7455         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7456
7457         cmd="$LFS find ! --mirror-state=sp --type f $td"
7458         nfiles=$($cmd | wc -l)
7459         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7460 }
7461 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7462
7463 test_57a() {
7464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7465         # note test will not do anything if MDS is not local
7466         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7467                 skip_env "ldiskfs only test"
7468         fi
7469         remote_mds_nodsh && skip "remote MDS with nodsh"
7470
7471         local MNTDEV="osd*.*MDT*.mntdev"
7472         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7473         [ -z "$DEV" ] && error "can't access $MNTDEV"
7474         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7475                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7476                         error "can't access $DEV"
7477                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7478                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7479                 rm $TMP/t57a.dump
7480         done
7481 }
7482 run_test 57a "verify MDS filesystem created with large inodes =="
7483
7484 test_57b() {
7485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7486         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7487                 skip_env "ldiskfs only test"
7488         fi
7489         remote_mds_nodsh && skip "remote MDS with nodsh"
7490
7491         local dir=$DIR/$tdir
7492         local filecount=100
7493         local file1=$dir/f1
7494         local fileN=$dir/f$filecount
7495
7496         rm -rf $dir || error "removing $dir"
7497         test_mkdir -c1 $dir
7498         local mdtidx=$($LFS getstripe -m $dir)
7499         local mdtname=MDT$(printf %04x $mdtidx)
7500         local facet=mds$((mdtidx + 1))
7501
7502         echo "mcreating $filecount files"
7503         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7504
7505         # verify that files do not have EAs yet
7506         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7507                 error "$file1 has an EA"
7508         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7509                 error "$fileN has an EA"
7510
7511         sync
7512         sleep 1
7513         df $dir  #make sure we get new statfs data
7514         local mdsfree=$(do_facet $facet \
7515                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7516         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7517         local file
7518
7519         echo "opening files to create objects/EAs"
7520         for file in $(seq -f $dir/f%g 1 $filecount); do
7521                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7522                         error "opening $file"
7523         done
7524
7525         # verify that files have EAs now
7526         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7527         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7528
7529         sleep 1  #make sure we get new statfs data
7530         df $dir
7531         local mdsfree2=$(do_facet $facet \
7532                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7533         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7534
7535         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7536                 if [ "$mdsfree" != "$mdsfree2" ]; then
7537                         error "MDC before $mdcfree != after $mdcfree2"
7538                 else
7539                         echo "MDC before $mdcfree != after $mdcfree2"
7540                         echo "unable to confirm if MDS has large inodes"
7541                 fi
7542         fi
7543         rm -rf $dir
7544 }
7545 run_test 57b "default LOV EAs are stored inside large inodes ==="
7546
7547 test_58() {
7548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7549         [ -z "$(which wiretest 2>/dev/null)" ] &&
7550                         skip_env "could not find wiretest"
7551
7552         wiretest
7553 }
7554 run_test 58 "verify cross-platform wire constants =============="
7555
7556 test_59() {
7557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7558
7559         echo "touch 130 files"
7560         createmany -o $DIR/f59- 130
7561         echo "rm 130 files"
7562         unlinkmany $DIR/f59- 130
7563         sync
7564         # wait for commitment of removal
7565         wait_delete_completed
7566 }
7567 run_test 59 "verify cancellation of llog records async ========="
7568
7569 TEST60_HEAD="test_60 run $RANDOM"
7570 test_60a() {
7571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7572         remote_mgs_nodsh && skip "remote MGS with nodsh"
7573         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7574                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7575                         skip_env "missing subtest run-llog.sh"
7576
7577         log "$TEST60_HEAD - from kernel mode"
7578         do_facet mgs "$LCTL dk > /dev/null"
7579         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7580         do_facet mgs $LCTL dk > $TMP/$tfile
7581
7582         # LU-6388: test llog_reader
7583         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7584         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7585         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7586                         skip_env "missing llog_reader"
7587         local fstype=$(facet_fstype mgs)
7588         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7589                 skip_env "Only for ldiskfs or zfs type mgs"
7590
7591         local mntpt=$(facet_mntpt mgs)
7592         local mgsdev=$(mgsdevname 1)
7593         local fid_list
7594         local fid
7595         local rec_list
7596         local rec
7597         local rec_type
7598         local obj_file
7599         local path
7600         local seq
7601         local oid
7602         local pass=true
7603
7604         #get fid and record list
7605         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7606                 tail -n 4))
7607         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7608                 tail -n 4))
7609         #remount mgs as ldiskfs or zfs type
7610         stop mgs || error "stop mgs failed"
7611         mount_fstype mgs || error "remount mgs failed"
7612         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7613                 fid=${fid_list[i]}
7614                 rec=${rec_list[i]}
7615                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7616                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7617                 oid=$((16#$oid))
7618
7619                 case $fstype in
7620                         ldiskfs )
7621                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7622                         zfs )
7623                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7624                 esac
7625                 echo "obj_file is $obj_file"
7626                 do_facet mgs $llog_reader $obj_file
7627
7628                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7629                         awk '{ print $3 }' | sed -e "s/^type=//g")
7630                 if [ $rec_type != $rec ]; then
7631                         echo "FAILED test_60a wrong record type $rec_type," \
7632                               "should be $rec"
7633                         pass=false
7634                         break
7635                 fi
7636
7637                 #check obj path if record type is LLOG_LOGID_MAGIC
7638                 if [ "$rec" == "1064553b" ]; then
7639                         path=$(do_facet mgs $llog_reader $obj_file |
7640                                 grep "path=" | awk '{ print $NF }' |
7641                                 sed -e "s/^path=//g")
7642                         if [ $obj_file != $mntpt/$path ]; then
7643                                 echo "FAILED test_60a wrong obj path" \
7644                                       "$montpt/$path, should be $obj_file"
7645                                 pass=false
7646                                 break
7647                         fi
7648                 fi
7649         done
7650         rm -f $TMP/$tfile
7651         #restart mgs before "error", otherwise it will block the next test
7652         stop mgs || error "stop mgs failed"
7653         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7654         $pass || error "test failed, see FAILED test_60a messages for specifics"
7655 }
7656 run_test 60a "llog_test run from kernel module and test llog_reader"
7657
7658 test_60b() { # bug 6411
7659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7660
7661         dmesg > $DIR/$tfile
7662         LLOG_COUNT=$(do_facet mgs dmesg |
7663                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7664                           /llog_[a-z]*.c:[0-9]/ {
7665                                 if (marker)
7666                                         from_marker++
7667                                 from_begin++
7668                           }
7669                           END {
7670                                 if (marker)
7671                                         print from_marker
7672                                 else
7673                                         print from_begin
7674                           }")
7675
7676         [[ $LLOG_COUNT -gt 120 ]] &&
7677                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7678 }
7679 run_test 60b "limit repeated messages from CERROR/CWARN"
7680
7681 test_60c() {
7682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7683
7684         echo "create 5000 files"
7685         createmany -o $DIR/f60c- 5000
7686 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7687         lctl set_param fail_loc=0x80000137
7688         unlinkmany $DIR/f60c- 5000
7689         lctl set_param fail_loc=0
7690 }
7691 run_test 60c "unlink file when mds full"
7692
7693 test_60d() {
7694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7695
7696         SAVEPRINTK=$(lctl get_param -n printk)
7697         # verify "lctl mark" is even working"
7698         MESSAGE="test message ID $RANDOM $$"
7699         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7700         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7701
7702         lctl set_param printk=0 || error "set lnet.printk failed"
7703         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7704         MESSAGE="new test message ID $RANDOM $$"
7705         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7706         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7707         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7708
7709         lctl set_param -n printk="$SAVEPRINTK"
7710 }
7711 run_test 60d "test printk console message masking"
7712
7713 test_60e() {
7714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7715         remote_mds_nodsh && skip "remote MDS with nodsh"
7716
7717         touch $DIR/$tfile
7718 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7719         do_facet mds1 lctl set_param fail_loc=0x15b
7720         rm $DIR/$tfile
7721 }
7722 run_test 60e "no space while new llog is being created"
7723
7724 test_60g() {
7725         local pid
7726         local i
7727
7728         test_mkdir -c $MDSCOUNT $DIR/$tdir
7729
7730         (
7731                 local index=0
7732                 while true; do
7733                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7734                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7735                                 2>/dev/null
7736                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7737                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7738                         index=$((index + 1))
7739                 done
7740         ) &
7741
7742         pid=$!
7743
7744         for i in {0..100}; do
7745                 # define OBD_FAIL_OSD_TXN_START    0x19a
7746                 local index=$((i % MDSCOUNT + 1))
7747
7748                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7749                         > /dev/null
7750                 sleep 0.01
7751         done
7752
7753         kill -9 $pid
7754
7755         for i in $(seq $MDSCOUNT); do
7756                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7757         done
7758
7759         mkdir $DIR/$tdir/new || error "mkdir failed"
7760         rmdir $DIR/$tdir/new || error "rmdir failed"
7761
7762         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7763                 -t namespace
7764         for i in $(seq $MDSCOUNT); do
7765                 wait_update_facet mds$i "$LCTL get_param -n \
7766                         mdd.$(facet_svc mds$i).lfsck_namespace |
7767                         awk '/^status/ { print \\\$2 }'" "completed"
7768         done
7769
7770         ls -R $DIR/$tdir || error "ls failed"
7771         rm -rf $DIR/$tdir || error "rmdir failed"
7772 }
7773 run_test 60g "transaction abort won't cause MDT hung"
7774
7775 test_60h() {
7776         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7777                 skip "Need MDS version at least 2.12.52"
7778         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7779
7780         local f
7781
7782         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7783         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7784         for fail_loc in 0x80000188 0x80000189; do
7785                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7786                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7787                         error "mkdir $dir-$fail_loc failed"
7788                 for i in {0..10}; do
7789                         # create may fail on missing stripe
7790                         echo $i > $DIR/$tdir-$fail_loc/$i
7791                 done
7792                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7793                         error "getdirstripe $tdir-$fail_loc failed"
7794                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7795                         error "migrate $tdir-$fail_loc failed"
7796                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7797                         error "getdirstripe $tdir-$fail_loc failed"
7798                 pushd $DIR/$tdir-$fail_loc
7799                 for f in *; do
7800                         echo $f | cmp $f - || error "$f data mismatch"
7801                 done
7802                 popd
7803                 rm -rf $DIR/$tdir-$fail_loc
7804         done
7805 }
7806 run_test 60h "striped directory with missing stripes can be accessed"
7807
7808 test_61a() {
7809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7810
7811         f="$DIR/f61"
7812         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7813         cancel_lru_locks osc
7814         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7815         sync
7816 }
7817 run_test 61a "mmap() writes don't make sync hang ================"
7818
7819 test_61b() {
7820         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7821 }
7822 run_test 61b "mmap() of unstriped file is successful"
7823
7824 # bug 2330 - insufficient obd_match error checking causes LBUG
7825 test_62() {
7826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7827
7828         f="$DIR/f62"
7829         echo foo > $f
7830         cancel_lru_locks osc
7831         lctl set_param fail_loc=0x405
7832         cat $f && error "cat succeeded, expect -EIO"
7833         lctl set_param fail_loc=0
7834 }
7835 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7836 # match every page all of the time.
7837 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7838
7839 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7840 # Though this test is irrelevant anymore, it helped to reveal some
7841 # other grant bugs (LU-4482), let's keep it.
7842 test_63a() {   # was test_63
7843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7844
7845         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7846
7847         for i in `seq 10` ; do
7848                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7849                 sleep 5
7850                 kill $!
7851                 sleep 1
7852         done
7853
7854         rm -f $DIR/f63 || true
7855 }
7856 run_test 63a "Verify oig_wait interruption does not crash ======="
7857
7858 # bug 2248 - async write errors didn't return to application on sync
7859 # bug 3677 - async write errors left page locked
7860 test_63b() {
7861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7862
7863         debugsave
7864         lctl set_param debug=-1
7865
7866         # ensure we have a grant to do async writes
7867         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7868         rm $DIR/$tfile
7869
7870         sync    # sync lest earlier test intercept the fail_loc
7871
7872         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7873         lctl set_param fail_loc=0x80000406
7874         $MULTIOP $DIR/$tfile Owy && \
7875                 error "sync didn't return ENOMEM"
7876         sync; sleep 2; sync     # do a real sync this time to flush page
7877         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7878                 error "locked page left in cache after async error" || true
7879         debugrestore
7880 }
7881 run_test 63b "async write errors should be returned to fsync ==="
7882
7883 test_64a () {
7884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7885
7886         lfs df $DIR
7887         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7888 }
7889 run_test 64a "verify filter grant calculations (in kernel) ====="
7890
7891 test_64b () {
7892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7893
7894         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7895 }
7896 run_test 64b "check out-of-space detection on client"
7897
7898 test_64c() {
7899         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7900 }
7901 run_test 64c "verify grant shrink"
7902
7903 import_param() {
7904         local tgt=$1
7905         local param=$2
7906
7907         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7908 }
7909
7910 # this does exactly what osc_request.c:osc_announce_cached() does in
7911 # order to calculate max amount of grants to ask from server
7912 want_grant() {
7913         local tgt=$1
7914
7915         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7916         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7917
7918         ((rpc_in_flight++));
7919         nrpages=$((nrpages * rpc_in_flight))
7920
7921         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7922
7923         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7924
7925         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7926         local undirty=$((nrpages * PAGE_SIZE))
7927
7928         local max_extent_pages
7929         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7930         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7931         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7932         local grant_extent_tax
7933         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7934
7935         undirty=$((undirty + nrextents * grant_extent_tax))
7936
7937         echo $undirty
7938 }
7939
7940 # this is size of unit for grant allocation. It should be equal to
7941 # what tgt_grant.c:tgt_grant_chunk() calculates
7942 grant_chunk() {
7943         local tgt=$1
7944         local max_brw_size
7945         local grant_extent_tax
7946
7947         max_brw_size=$(import_param $tgt max_brw_size)
7948
7949         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7950
7951         echo $(((max_brw_size + grant_extent_tax) * 2))
7952 }
7953
7954 test_64d() {
7955         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7956                 skip "OST < 2.10.55 doesn't limit grants enough"
7957
7958         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7959
7960         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7961                 skip "no grant_param connect flag"
7962
7963         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7964
7965         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7966         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7967
7968
7969         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7970         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7971
7972         $LFS setstripe $DIR/$tfile -i 0 -c 1
7973         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7974         ddpid=$!
7975
7976         while kill -0 $ddpid; do
7977                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7978
7979                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7980                         kill $ddpid
7981                         error "cur_grant $cur_grant > $max_cur_granted"
7982                 fi
7983
7984                 sleep 1
7985         done
7986 }
7987 run_test 64d "check grant limit exceed"
7988
7989 check_grants() {
7990         local tgt=$1
7991         local expected=$2
7992         local msg=$3
7993         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7994
7995         ((cur_grants == expected)) ||
7996                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7997 }
7998
7999 round_up_p2() {
8000         echo $((($1 + $2 - 1) & ~($2 - 1)))
8001 }
8002
8003 test_64e() {
8004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8005         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8006                 skip "Need OSS version at least 2.11.56"
8007
8008         # Remount client to reset grant
8009         remount_client $MOUNT || error "failed to remount client"
8010         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8011
8012         local init_grants=$(import_param $osc_tgt initial_grant)
8013
8014         check_grants $osc_tgt $init_grants "init grants"
8015
8016         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8017         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8018         local gbs=$(import_param $osc_tgt grant_block_size)
8019
8020         # write random number of bytes from max_brw_size / 4 to max_brw_size
8021         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8022         # align for direct io
8023         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8024         # round to grant consumption unit
8025         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8026
8027         local grants=$((wb_round_up + extent_tax))
8028
8029         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8030
8031         # define OBD_FAIL_TGT_NO_GRANT 0x725
8032         # make the server not grant more back
8033         do_facet ost1 $LCTL set_param fail_loc=0x725
8034         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8035
8036         do_facet ost1 $LCTL set_param fail_loc=0
8037
8038         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8039
8040         rm -f $DIR/$tfile || error "rm failed"
8041
8042         # Remount client to reset grant
8043         remount_client $MOUNT || error "failed to remount client"
8044         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8045
8046         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8047
8048         # define OBD_FAIL_TGT_NO_GRANT 0x725
8049         # make the server not grant more back
8050         do_facet ost1 $LCTL set_param fail_loc=0x725
8051         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8052         do_facet ost1 $LCTL set_param fail_loc=0
8053
8054         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8055 }
8056 run_test 64e "check grant consumption (no grant allocation)"
8057
8058 test_64f() {
8059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8060
8061         # Remount client to reset grant
8062         remount_client $MOUNT || error "failed to remount client"
8063         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8064
8065         local init_grants=$(import_param $osc_tgt initial_grant)
8066         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8067         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8068         local gbs=$(import_param $osc_tgt grant_block_size)
8069         local chunk=$(grant_chunk $osc_tgt)
8070
8071         # write random number of bytes from max_brw_size / 4 to max_brw_size
8072         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8073         # align for direct io
8074         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8075         # round to grant consumption unit
8076         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8077
8078         local grants=$((wb_round_up + extent_tax))
8079
8080         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8081         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8082                 error "error writing to $DIR/$tfile"
8083
8084         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8085                 "direct io with grant allocation"
8086
8087         rm -f $DIR/$tfile || error "rm failed"
8088
8089         # Remount client to reset grant
8090         remount_client $MOUNT || error "failed to remount client"
8091         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8092
8093         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8094
8095         local cmd="oO_WRONLY:w${write_bytes}_yc"
8096
8097         $MULTIOP $DIR/$tfile $cmd &
8098         MULTIPID=$!
8099         sleep 1
8100
8101         check_grants $osc_tgt $((init_grants - grants)) \
8102                 "buffered io, not write rpc"
8103
8104         kill -USR1 $MULTIPID
8105         wait
8106
8107         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8108                 "buffered io, one RPC"
8109 }
8110 run_test 64f "check grant consumption (with grant allocation)"
8111
8112 # bug 1414 - set/get directories' stripe info
8113 test_65a() {
8114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8115
8116         test_mkdir $DIR/$tdir
8117         touch $DIR/$tdir/f1
8118         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8119 }
8120 run_test 65a "directory with no stripe info"
8121
8122 test_65b() {
8123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8124
8125         test_mkdir $DIR/$tdir
8126         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8127
8128         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8129                                                 error "setstripe"
8130         touch $DIR/$tdir/f2
8131         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8132 }
8133 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8134
8135 test_65c() {
8136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8137         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8138
8139         test_mkdir $DIR/$tdir
8140         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8141
8142         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8143                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8144         touch $DIR/$tdir/f3
8145         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8146 }
8147 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8148
8149 test_65d() {
8150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8151
8152         test_mkdir $DIR/$tdir
8153         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8154         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8155
8156         if [[ $STRIPECOUNT -le 0 ]]; then
8157                 sc=1
8158         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8159                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8160                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8161         else
8162                 sc=$(($STRIPECOUNT - 1))
8163         fi
8164         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8165         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8166         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8167                 error "lverify failed"
8168 }
8169 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8170
8171 test_65e() {
8172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8173
8174         test_mkdir $DIR/$tdir
8175
8176         $LFS setstripe $DIR/$tdir || error "setstripe"
8177         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8178                                         error "no stripe info failed"
8179         touch $DIR/$tdir/f6
8180         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8181 }
8182 run_test 65e "directory setstripe defaults"
8183
8184 test_65f() {
8185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8186
8187         test_mkdir $DIR/${tdir}f
8188         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8189                 error "setstripe succeeded" || true
8190 }
8191 run_test 65f "dir setstripe permission (should return error) ==="
8192
8193 test_65g() {
8194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8195
8196         test_mkdir $DIR/$tdir
8197         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8198
8199         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8200                 error "setstripe -S failed"
8201         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8202         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8203                 error "delete default stripe failed"
8204 }
8205 run_test 65g "directory setstripe -d"
8206
8207 test_65h() {
8208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8209
8210         test_mkdir $DIR/$tdir
8211         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8212
8213         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8214                 error "setstripe -S failed"
8215         test_mkdir $DIR/$tdir/dd1
8216         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8217                 error "stripe info inherit failed"
8218 }
8219 run_test 65h "directory stripe info inherit ===================="
8220
8221 test_65i() {
8222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8223
8224         save_layout_restore_at_exit $MOUNT
8225
8226         # bug6367: set non-default striping on root directory
8227         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8228
8229         # bug12836: getstripe on -1 default directory striping
8230         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8231
8232         # bug12836: getstripe -v on -1 default directory striping
8233         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8234
8235         # bug12836: new find on -1 default directory striping
8236         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8237 }
8238 run_test 65i "various tests to set root directory striping"
8239
8240 test_65j() { # bug6367
8241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8242
8243         sync; sleep 1
8244
8245         # if we aren't already remounting for each test, do so for this test
8246         if [ "$I_MOUNTED" = "yes" ]; then
8247                 cleanup || error "failed to unmount"
8248                 setup
8249         fi
8250
8251         save_layout_restore_at_exit $MOUNT
8252
8253         $LFS setstripe -d $MOUNT || error "setstripe failed"
8254 }
8255 run_test 65j "set default striping on root directory (bug 6367)="
8256
8257 cleanup_65k() {
8258         rm -rf $DIR/$tdir
8259         wait_delete_completed
8260         do_facet $SINGLEMDS "lctl set_param -n \
8261                 osp.$ost*MDT0000.max_create_count=$max_count"
8262         do_facet $SINGLEMDS "lctl set_param -n \
8263                 osp.$ost*MDT0000.create_count=$count"
8264         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8265         echo $INACTIVE_OSC "is Activate"
8266
8267         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8268 }
8269
8270 test_65k() { # bug11679
8271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8272         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8273         remote_mds_nodsh && skip "remote MDS with nodsh"
8274
8275         local disable_precreate=true
8276         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8277                 disable_precreate=false
8278
8279         echo "Check OST status: "
8280         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8281                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8282
8283         for OSC in $MDS_OSCS; do
8284                 echo $OSC "is active"
8285                 do_facet $SINGLEMDS lctl --device %$OSC activate
8286         done
8287
8288         for INACTIVE_OSC in $MDS_OSCS; do
8289                 local ost=$(osc_to_ost $INACTIVE_OSC)
8290                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8291                                lov.*md*.target_obd |
8292                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8293
8294                 mkdir -p $DIR/$tdir
8295                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8296                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8297
8298                 echo "Deactivate: " $INACTIVE_OSC
8299                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8300
8301                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8302                               osp.$ost*MDT0000.create_count")
8303                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8304                                   osp.$ost*MDT0000.max_create_count")
8305                 $disable_precreate &&
8306                         do_facet $SINGLEMDS "lctl set_param -n \
8307                                 osp.$ost*MDT0000.max_create_count=0"
8308
8309                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8310                         [ -f $DIR/$tdir/$idx ] && continue
8311                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8312                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8313                                 { cleanup_65k;
8314                                   error "setstripe $idx should succeed"; }
8315                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8316                 done
8317                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8318                 rmdir $DIR/$tdir
8319
8320                 do_facet $SINGLEMDS "lctl set_param -n \
8321                         osp.$ost*MDT0000.max_create_count=$max_count"
8322                 do_facet $SINGLEMDS "lctl set_param -n \
8323                         osp.$ost*MDT0000.create_count=$count"
8324                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8325                 echo $INACTIVE_OSC "is Activate"
8326
8327                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8328         done
8329 }
8330 run_test 65k "validate manual striping works properly with deactivated OSCs"
8331
8332 test_65l() { # bug 12836
8333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8334
8335         test_mkdir -p $DIR/$tdir/test_dir
8336         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8337         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8338 }
8339 run_test 65l "lfs find on -1 stripe dir ========================"
8340
8341 test_65m() {
8342         local layout=$(save_layout $MOUNT)
8343         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8344                 restore_layout $MOUNT $layout
8345                 error "setstripe should fail by non-root users"
8346         }
8347         true
8348 }
8349 run_test 65m "normal user can't set filesystem default stripe"
8350
8351 test_65n() {
8352         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8353         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8354                 skip "Need MDS version at least 2.12.50"
8355         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8356
8357         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8358         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8359         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8360
8361         local root_layout=$(save_layout $MOUNT)
8362         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8363
8364         # new subdirectory under root directory should not inherit
8365         # the default layout from root
8366         local dir1=$MOUNT/$tdir-1
8367         mkdir $dir1 || error "mkdir $dir1 failed"
8368         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8369                 error "$dir1 shouldn't have LOV EA"
8370
8371         # delete the default layout on root directory
8372         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8373
8374         local dir2=$MOUNT/$tdir-2
8375         mkdir $dir2 || error "mkdir $dir2 failed"
8376         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8377                 error "$dir2 shouldn't have LOV EA"
8378
8379         # set a new striping pattern on root directory
8380         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8381         local new_def_stripe_size=$((def_stripe_size * 2))
8382         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8383                 error "set stripe size on $MOUNT failed"
8384
8385         # new file created in $dir2 should inherit the new stripe size from
8386         # the filesystem default
8387         local file2=$dir2/$tfile-2
8388         touch $file2 || error "touch $file2 failed"
8389
8390         local file2_stripe_size=$($LFS getstripe -S $file2)
8391         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8392                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8393
8394         local dir3=$MOUNT/$tdir-3
8395         mkdir $dir3 || error "mkdir $dir3 failed"
8396         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8397         # the root layout, which is the actual default layout that will be used
8398         # when new files are created in $dir3.
8399         local dir3_layout=$(get_layout_param $dir3)
8400         local root_dir_layout=$(get_layout_param $MOUNT)
8401         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8402                 error "$dir3 should show the default layout from $MOUNT"
8403
8404         # set OST pool on root directory
8405         local pool=$TESTNAME
8406         pool_add $pool || error "add $pool failed"
8407         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8408                 error "add targets to $pool failed"
8409
8410         $LFS setstripe -p $pool $MOUNT ||
8411                 error "set OST pool on $MOUNT failed"
8412
8413         # new file created in $dir3 should inherit the pool from
8414         # the filesystem default
8415         local file3=$dir3/$tfile-3
8416         touch $file3 || error "touch $file3 failed"
8417
8418         local file3_pool=$($LFS getstripe -p $file3)
8419         [[ "$file3_pool" = "$pool" ]] ||
8420                 error "$file3 didn't inherit OST pool $pool"
8421
8422         local dir4=$MOUNT/$tdir-4
8423         mkdir $dir4 || error "mkdir $dir4 failed"
8424         local dir4_layout=$(get_layout_param $dir4)
8425         root_dir_layout=$(get_layout_param $MOUNT)
8426         echo "$LFS getstripe -d $dir4"
8427         $LFS getstripe -d $dir4
8428         echo "$LFS getstripe -d $MOUNT"
8429         $LFS getstripe -d $MOUNT
8430         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8431                 error "$dir4 should show the default layout from $MOUNT"
8432
8433         # new file created in $dir4 should inherit the pool from
8434         # the filesystem default
8435         local file4=$dir4/$tfile-4
8436         touch $file4 || error "touch $file4 failed"
8437
8438         local file4_pool=$($LFS getstripe -p $file4)
8439         [[ "$file4_pool" = "$pool" ]] ||
8440                 error "$file4 didn't inherit OST pool $pool"
8441
8442         # new subdirectory under non-root directory should inherit
8443         # the default layout from its parent directory
8444         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8445                 error "set directory layout on $dir4 failed"
8446
8447         local dir5=$dir4/$tdir-5
8448         mkdir $dir5 || error "mkdir $dir5 failed"
8449
8450         dir4_layout=$(get_layout_param $dir4)
8451         local dir5_layout=$(get_layout_param $dir5)
8452         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8453                 error "$dir5 should inherit the default layout from $dir4"
8454
8455         # though subdir under ROOT doesn't inherit default layout, but
8456         # its sub dir/file should be created with default layout.
8457         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8458         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8459                 skip "Need MDS version at least 2.12.59"
8460
8461         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8462         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8463         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8464
8465         if [ $default_lmv_hash == "none" ]; then
8466                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8467         else
8468                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8469                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8470         fi
8471
8472         $LFS setdirstripe -D -c 2 $MOUNT ||
8473                 error "setdirstripe -D -c 2 failed"
8474         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8475         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8476         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8477 }
8478 run_test 65n "don't inherit default layout from root for new subdirectories"
8479
8480 # bug 2543 - update blocks count on client
8481 test_66() {
8482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8483
8484         COUNT=${COUNT:-8}
8485         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8486         sync; sync_all_data; sync; sync_all_data
8487         cancel_lru_locks osc
8488         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8489         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8490 }
8491 run_test 66 "update inode blocks count on client ==============="
8492
8493 meminfo() {
8494         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8495 }
8496
8497 swap_used() {
8498         swapon -s | awk '($1 == "'$1'") { print $4 }'
8499 }
8500
8501 # bug5265, obdfilter oa2dentry return -ENOENT
8502 # #define OBD_FAIL_SRV_ENOENT 0x217
8503 test_69() {
8504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8505         remote_ost_nodsh && skip "remote OST with nodsh"
8506
8507         f="$DIR/$tfile"
8508         $LFS setstripe -c 1 -i 0 $f
8509
8510         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8511
8512         do_facet ost1 lctl set_param fail_loc=0x217
8513         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8514         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8515
8516         do_facet ost1 lctl set_param fail_loc=0
8517         $DIRECTIO write $f 0 2 || error "write error"
8518
8519         cancel_lru_locks osc
8520         $DIRECTIO read $f 0 1 || error "read error"
8521
8522         do_facet ost1 lctl set_param fail_loc=0x217
8523         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8524
8525         do_facet ost1 lctl set_param fail_loc=0
8526         rm -f $f
8527 }
8528 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8529
8530 test_71() {
8531         test_mkdir $DIR/$tdir
8532         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8533         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8534 }
8535 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8536
8537 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8539         [ "$RUNAS_ID" = "$UID" ] &&
8540                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8541         # Check that testing environment is properly set up. Skip if not
8542         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8543                 skip_env "User $RUNAS_ID does not exist - skipping"
8544
8545         touch $DIR/$tfile
8546         chmod 777 $DIR/$tfile
8547         chmod ug+s $DIR/$tfile
8548         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8549                 error "$RUNAS dd $DIR/$tfile failed"
8550         # See if we are still setuid/sgid
8551         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8552                 error "S/gid is not dropped on write"
8553         # Now test that MDS is updated too
8554         cancel_lru_locks mdc
8555         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8556                 error "S/gid is not dropped on MDS"
8557         rm -f $DIR/$tfile
8558 }
8559 run_test 72a "Test that remove suid works properly (bug5695) ===="
8560
8561 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8562         local perm
8563
8564         [ "$RUNAS_ID" = "$UID" ] &&
8565                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8566         [ "$RUNAS_ID" -eq 0 ] &&
8567                 skip_env "RUNAS_ID = 0 -- skipping"
8568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8569         # Check that testing environment is properly set up. Skip if not
8570         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8571                 skip_env "User $RUNAS_ID does not exist - skipping"
8572
8573         touch $DIR/${tfile}-f{g,u}
8574         test_mkdir $DIR/${tfile}-dg
8575         test_mkdir $DIR/${tfile}-du
8576         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8577         chmod g+s $DIR/${tfile}-{f,d}g
8578         chmod u+s $DIR/${tfile}-{f,d}u
8579         for perm in 777 2777 4777; do
8580                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8581                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8582                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8583                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8584         done
8585         true
8586 }
8587 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8588
8589 # bug 3462 - multiple simultaneous MDC requests
8590 test_73() {
8591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8592
8593         test_mkdir $DIR/d73-1
8594         test_mkdir $DIR/d73-2
8595         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8596         pid1=$!
8597
8598         lctl set_param fail_loc=0x80000129
8599         $MULTIOP $DIR/d73-1/f73-2 Oc &
8600         sleep 1
8601         lctl set_param fail_loc=0
8602
8603         $MULTIOP $DIR/d73-2/f73-3 Oc &
8604         pid3=$!
8605
8606         kill -USR1 $pid1
8607         wait $pid1 || return 1
8608
8609         sleep 25
8610
8611         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8612         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8613         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8614
8615         rm -rf $DIR/d73-*
8616 }
8617 run_test 73 "multiple MDC requests (should not deadlock)"
8618
8619 test_74a() { # bug 6149, 6184
8620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8621
8622         touch $DIR/f74a
8623         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8624         #
8625         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8626         # will spin in a tight reconnection loop
8627         $LCTL set_param fail_loc=0x8000030e
8628         # get any lock that won't be difficult - lookup works.
8629         ls $DIR/f74a
8630         $LCTL set_param fail_loc=0
8631         rm -f $DIR/f74a
8632         true
8633 }
8634 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8635
8636 test_74b() { # bug 13310
8637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8638
8639         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8640         #
8641         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8642         # will spin in a tight reconnection loop
8643         $LCTL set_param fail_loc=0x8000030e
8644         # get a "difficult" lock
8645         touch $DIR/f74b
8646         $LCTL set_param fail_loc=0
8647         rm -f $DIR/f74b
8648         true
8649 }
8650 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8651
8652 test_74c() {
8653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8654
8655         #define OBD_FAIL_LDLM_NEW_LOCK
8656         $LCTL set_param fail_loc=0x319
8657         touch $DIR/$tfile && error "touch successful"
8658         $LCTL set_param fail_loc=0
8659         true
8660 }
8661 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8662
8663 slab_lic=/sys/kernel/slab/lustre_inode_cache
8664 num_objects() {
8665         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8666         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8667                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8668 }
8669
8670 test_76a() { # Now for b=20433, added originally in b=1443
8671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8672
8673         cancel_lru_locks osc
8674         # there may be some slab objects cached per core
8675         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8676         local before=$(num_objects)
8677         local count=$((512 * cpus))
8678         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8679         local margin=$((count / 10))
8680         if [[ -f $slab_lic/aliases ]]; then
8681                 local aliases=$(cat $slab_lic/aliases)
8682                 (( aliases > 0 )) && margin=$((margin * aliases))
8683         fi
8684
8685         echo "before slab objects: $before"
8686         for i in $(seq $count); do
8687                 touch $DIR/$tfile
8688                 rm -f $DIR/$tfile
8689         done
8690         cancel_lru_locks osc
8691         local after=$(num_objects)
8692         echo "created: $count, after slab objects: $after"
8693         # shared slab counts are not very accurate, allow significant margin
8694         # the main goal is that the cache growth is not permanently > $count
8695         while (( after > before + margin )); do
8696                 sleep 1
8697                 after=$(num_objects)
8698                 wait=$((wait + 1))
8699                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8700                 if (( wait > 60 )); then
8701                         error "inode slab grew from $before+$margin to $after"
8702                 fi
8703         done
8704 }
8705 run_test 76a "confirm clients recycle inodes properly ===="
8706
8707 test_76b() {
8708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8709         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8710
8711         local count=512
8712         local before=$(num_objects)
8713
8714         for i in $(seq $count); do
8715                 mkdir $DIR/$tdir
8716                 rmdir $DIR/$tdir
8717         done
8718
8719         local after=$(num_objects)
8720         local wait=0
8721
8722         while (( after > before )); do
8723                 sleep 1
8724                 after=$(num_objects)
8725                 wait=$((wait + 1))
8726                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8727                 if (( wait > 60 )); then
8728                         error "inode slab grew from $before to $after"
8729                 fi
8730         done
8731
8732         echo "slab objects before: $before, after: $after"
8733 }
8734 run_test 76b "confirm clients recycle directory inodes properly ===="
8735
8736 export ORIG_CSUM=""
8737 set_checksums()
8738 {
8739         # Note: in sptlrpc modes which enable its own bulk checksum, the
8740         # original crc32_le bulk checksum will be automatically disabled,
8741         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8742         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8743         # In this case set_checksums() will not be no-op, because sptlrpc
8744         # bulk checksum will be enabled all through the test.
8745
8746         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8747         lctl set_param -n osc.*.checksums $1
8748         return 0
8749 }
8750
8751 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8752                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8753 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8754                              tr -d [] | head -n1)}
8755 set_checksum_type()
8756 {
8757         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8758         rc=$?
8759         log "set checksum type to $1, rc = $rc"
8760         return $rc
8761 }
8762
8763 get_osc_checksum_type()
8764 {
8765         # arugment 1: OST name, like OST0000
8766         ost=$1
8767         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8768                         sed 's/.*\[\(.*\)\].*/\1/g')
8769         rc=$?
8770         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8771         echo $checksum_type
8772 }
8773
8774 F77_TMP=$TMP/f77-temp
8775 F77SZ=8
8776 setup_f77() {
8777         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8778                 error "error writing to $F77_TMP"
8779 }
8780
8781 test_77a() { # bug 10889
8782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8783         $GSS && skip_env "could not run with gss"
8784
8785         [ ! -f $F77_TMP ] && setup_f77
8786         set_checksums 1
8787         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8788         set_checksums 0
8789         rm -f $DIR/$tfile
8790 }
8791 run_test 77a "normal checksum read/write operation"
8792
8793 test_77b() { # bug 10889
8794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8795         $GSS && skip_env "could not run with gss"
8796
8797         [ ! -f $F77_TMP ] && setup_f77
8798         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8799         $LCTL set_param fail_loc=0x80000409
8800         set_checksums 1
8801
8802         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8803                 error "dd error: $?"
8804         $LCTL set_param fail_loc=0
8805
8806         for algo in $CKSUM_TYPES; do
8807                 cancel_lru_locks osc
8808                 set_checksum_type $algo
8809                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8810                 $LCTL set_param fail_loc=0x80000408
8811                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8812                 $LCTL set_param fail_loc=0
8813         done
8814         set_checksums 0
8815         set_checksum_type $ORIG_CSUM_TYPE
8816         rm -f $DIR/$tfile
8817 }
8818 run_test 77b "checksum error on client write, read"
8819
8820 cleanup_77c() {
8821         trap 0
8822         set_checksums 0
8823         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8824         $check_ost &&
8825                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8826         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8827         $check_ost && [ -n "$ost_file_prefix" ] &&
8828                 do_facet ost1 rm -f ${ost_file_prefix}\*
8829 }
8830
8831 test_77c() {
8832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8833         $GSS && skip_env "could not run with gss"
8834         remote_ost_nodsh && skip "remote OST with nodsh"
8835
8836         local bad1
8837         local osc_file_prefix
8838         local osc_file
8839         local check_ost=false
8840         local ost_file_prefix
8841         local ost_file
8842         local orig_cksum
8843         local dump_cksum
8844         local fid
8845
8846         # ensure corruption will occur on first OSS/OST
8847         $LFS setstripe -i 0 $DIR/$tfile
8848
8849         [ ! -f $F77_TMP ] && setup_f77
8850         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8851                 error "dd write error: $?"
8852         fid=$($LFS path2fid $DIR/$tfile)
8853
8854         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8855         then
8856                 check_ost=true
8857                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8858                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8859         else
8860                 echo "OSS do not support bulk pages dump upon error"
8861         fi
8862
8863         osc_file_prefix=$($LCTL get_param -n debug_path)
8864         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8865
8866         trap cleanup_77c EXIT
8867
8868         set_checksums 1
8869         # enable bulk pages dump upon error on Client
8870         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8871         # enable bulk pages dump upon error on OSS
8872         $check_ost &&
8873                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8874
8875         # flush Client cache to allow next read to reach OSS
8876         cancel_lru_locks osc
8877
8878         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8879         $LCTL set_param fail_loc=0x80000408
8880         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8881         $LCTL set_param fail_loc=0
8882
8883         rm -f $DIR/$tfile
8884
8885         # check cksum dump on Client
8886         osc_file=$(ls ${osc_file_prefix}*)
8887         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8888         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8889         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8890         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8891         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8892                      cksum)
8893         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8894         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8895                 error "dump content does not match on Client"
8896
8897         $check_ost || skip "No need to check cksum dump on OSS"
8898
8899         # check cksum dump on OSS
8900         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8901         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8902         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8903         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8904         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8905                 error "dump content does not match on OSS"
8906
8907         cleanup_77c
8908 }
8909 run_test 77c "checksum error on client read with debug"
8910
8911 test_77d() { # bug 10889
8912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8913         $GSS && skip_env "could not run with gss"
8914
8915         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8916         $LCTL set_param fail_loc=0x80000409
8917         set_checksums 1
8918         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8919                 error "direct write: rc=$?"
8920         $LCTL set_param fail_loc=0
8921         set_checksums 0
8922
8923         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8924         $LCTL set_param fail_loc=0x80000408
8925         set_checksums 1
8926         cancel_lru_locks osc
8927         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8928                 error "direct read: rc=$?"
8929         $LCTL set_param fail_loc=0
8930         set_checksums 0
8931 }
8932 run_test 77d "checksum error on OST direct write, read"
8933
8934 test_77f() { # bug 10889
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936         $GSS && skip_env "could not run with gss"
8937
8938         set_checksums 1
8939         for algo in $CKSUM_TYPES; do
8940                 cancel_lru_locks osc
8941                 set_checksum_type $algo
8942                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8943                 $LCTL set_param fail_loc=0x409
8944                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8945                         error "direct write succeeded"
8946                 $LCTL set_param fail_loc=0
8947         done
8948         set_checksum_type $ORIG_CSUM_TYPE
8949         set_checksums 0
8950 }
8951 run_test 77f "repeat checksum error on write (expect error)"
8952
8953 test_77g() { # bug 10889
8954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8955         $GSS && skip_env "could not run with gss"
8956         remote_ost_nodsh && skip "remote OST with nodsh"
8957
8958         [ ! -f $F77_TMP ] && setup_f77
8959
8960         local file=$DIR/$tfile
8961         stack_trap "rm -f $file" EXIT
8962
8963         $LFS setstripe -c 1 -i 0 $file
8964         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8965         do_facet ost1 lctl set_param fail_loc=0x8000021a
8966         set_checksums 1
8967         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8968                 error "write error: rc=$?"
8969         do_facet ost1 lctl set_param fail_loc=0
8970         set_checksums 0
8971
8972         cancel_lru_locks osc
8973         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8974         do_facet ost1 lctl set_param fail_loc=0x8000021b
8975         set_checksums 1
8976         cmp $F77_TMP $file || error "file compare failed"
8977         do_facet ost1 lctl set_param fail_loc=0
8978         set_checksums 0
8979 }
8980 run_test 77g "checksum error on OST write, read"
8981
8982 test_77k() { # LU-10906
8983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8984         $GSS && skip_env "could not run with gss"
8985
8986         local cksum_param="osc.$FSNAME*.checksums"
8987         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8988         local checksum
8989         local i
8990
8991         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8992         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8993         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8994
8995         for i in 0 1; do
8996                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8997                         error "failed to set checksum=$i on MGS"
8998                 wait_update $HOSTNAME "$get_checksum" $i
8999                 #remount
9000                 echo "remount client, checksum should be $i"
9001                 remount_client $MOUNT || error "failed to remount client"
9002                 checksum=$(eval $get_checksum)
9003                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9004         done
9005         # remove persistent param to avoid races with checksum mountopt below
9006         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9007                 error "failed to delete checksum on MGS"
9008
9009         for opt in "checksum" "nochecksum"; do
9010                 #remount with mount option
9011                 echo "remount client with option $opt, checksum should be $i"
9012                 umount_client $MOUNT || error "failed to umount client"
9013                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9014                         error "failed to mount client with option '$opt'"
9015                 checksum=$(eval $get_checksum)
9016                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9017                 i=$((i - 1))
9018         done
9019
9020         remount_client $MOUNT || error "failed to remount client"
9021 }
9022 run_test 77k "enable/disable checksum correctly"
9023
9024 test_77l() {
9025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9026         $GSS && skip_env "could not run with gss"
9027
9028         set_checksums 1
9029         stack_trap "set_checksums $ORIG_CSUM" EXIT
9030         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9031
9032         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9033
9034         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9035         for algo in $CKSUM_TYPES; do
9036                 set_checksum_type $algo || error "fail to set checksum type $algo"
9037                 osc_algo=$(get_osc_checksum_type OST0000)
9038                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9039
9040                 # no locks, no reqs to let the connection idle
9041                 cancel_lru_locks osc
9042                 lru_resize_disable osc
9043                 wait_osc_import_state client ost1 IDLE
9044
9045                 # ensure ost1 is connected
9046                 stat $DIR/$tfile >/dev/null || error "can't stat"
9047                 wait_osc_import_state client ost1 FULL
9048
9049                 osc_algo=$(get_osc_checksum_type OST0000)
9050                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9051         done
9052         return 0
9053 }
9054 run_test 77l "preferred checksum type is remembered after reconnected"
9055
9056 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9057 rm -f $F77_TMP
9058 unset F77_TMP
9059
9060 cleanup_test_78() {
9061         trap 0
9062         rm -f $DIR/$tfile
9063 }
9064
9065 test_78() { # bug 10901
9066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9067         remote_ost || skip_env "local OST"
9068
9069         NSEQ=5
9070         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9071         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9072         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9073         echo "MemTotal: $MEMTOTAL"
9074
9075         # reserve 256MB of memory for the kernel and other running processes,
9076         # and then take 1/2 of the remaining memory for the read/write buffers.
9077         if [ $MEMTOTAL -gt 512 ] ;then
9078                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9079         else
9080                 # for those poor memory-starved high-end clusters...
9081                 MEMTOTAL=$((MEMTOTAL / 2))
9082         fi
9083         echo "Mem to use for directio: $MEMTOTAL"
9084
9085         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9086         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9087         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9088         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9089                 head -n1)
9090         echo "Smallest OST: $SMALLESTOST"
9091         [[ $SMALLESTOST -lt 10240 ]] &&
9092                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9093
9094         trap cleanup_test_78 EXIT
9095
9096         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9097                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9098
9099         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9100         echo "File size: $F78SIZE"
9101         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9102         for i in $(seq 1 $NSEQ); do
9103                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9104                 echo directIO rdwr round $i of $NSEQ
9105                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9106         done
9107
9108         cleanup_test_78
9109 }
9110 run_test 78 "handle large O_DIRECT writes correctly ============"
9111
9112 test_79() { # bug 12743
9113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9114
9115         wait_delete_completed
9116
9117         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9118         BKFREE=$(calc_osc_kbytes kbytesfree)
9119         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9120
9121         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9122         DFTOTAL=`echo $STRING | cut -d, -f1`
9123         DFUSED=`echo $STRING  | cut -d, -f2`
9124         DFAVAIL=`echo $STRING | cut -d, -f3`
9125         DFFREE=$(($DFTOTAL - $DFUSED))
9126
9127         ALLOWANCE=$((64 * $OSTCOUNT))
9128
9129         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9130            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9131                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9132         fi
9133         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9134            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9135                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9136         fi
9137         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9138            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9139                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9140         fi
9141 }
9142 run_test 79 "df report consistency check ======================="
9143
9144 test_80() { # bug 10718
9145         remote_ost_nodsh && skip "remote OST with nodsh"
9146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9147
9148         # relax strong synchronous semantics for slow backends like ZFS
9149         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9150                 local soc="obdfilter.*.sync_lock_cancel"
9151                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9152
9153                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9154                 if [ -z "$save" ]; then
9155                         soc="obdfilter.*.sync_on_lock_cancel"
9156                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9157                 fi
9158
9159                 if [ "$save" != "never" ]; then
9160                         local hosts=$(comma_list $(osts_nodes))
9161
9162                         do_nodes $hosts $LCTL set_param $soc=never
9163                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9164                 fi
9165         fi
9166
9167         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9168         sync; sleep 1; sync
9169         local before=$(date +%s)
9170         cancel_lru_locks osc
9171         local after=$(date +%s)
9172         local diff=$((after - before))
9173         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9174
9175         rm -f $DIR/$tfile
9176 }
9177 run_test 80 "Page eviction is equally fast at high offsets too"
9178
9179 test_81a() { # LU-456
9180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9181         remote_ost_nodsh && skip "remote OST with nodsh"
9182
9183         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9184         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9185         do_facet ost1 lctl set_param fail_loc=0x80000228
9186
9187         # write should trigger a retry and success
9188         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9189         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9190         RC=$?
9191         if [ $RC -ne 0 ] ; then
9192                 error "write should success, but failed for $RC"
9193         fi
9194 }
9195 run_test 81a "OST should retry write when get -ENOSPC ==============="
9196
9197 test_81b() { # LU-456
9198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9199         remote_ost_nodsh && skip "remote OST with nodsh"
9200
9201         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9202         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9203         do_facet ost1 lctl set_param fail_loc=0x228
9204
9205         # write should retry several times and return -ENOSPC finally
9206         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9207         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9208         RC=$?
9209         ENOSPC=28
9210         if [ $RC -ne $ENOSPC ] ; then
9211                 error "dd should fail for -ENOSPC, but succeed."
9212         fi
9213 }
9214 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9215
9216 test_99() {
9217         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9218
9219         test_mkdir $DIR/$tdir.cvsroot
9220         chown $RUNAS_ID $DIR/$tdir.cvsroot
9221
9222         cd $TMP
9223         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9224
9225         cd /etc/init.d
9226         # some versions of cvs import exit(1) when asked to import links or
9227         # files they can't read.  ignore those files.
9228         local toignore=$(find . -type l -printf '-I %f\n' -o \
9229                          ! -perm /4 -printf '-I %f\n')
9230         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9231                 $tdir.reposname vtag rtag
9232
9233         cd $DIR
9234         test_mkdir $DIR/$tdir.reposname
9235         chown $RUNAS_ID $DIR/$tdir.reposname
9236         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9237
9238         cd $DIR/$tdir.reposname
9239         $RUNAS touch foo99
9240         $RUNAS cvs add -m 'addmsg' foo99
9241         $RUNAS cvs update
9242         $RUNAS cvs commit -m 'nomsg' foo99
9243         rm -fr $DIR/$tdir.cvsroot
9244 }
9245 run_test 99 "cvs strange file/directory operations"
9246
9247 test_100() {
9248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9249         [[ "$NETTYPE" =~ tcp ]] ||
9250                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9251         remote_ost_nodsh && skip "remote OST with nodsh"
9252         remote_mds_nodsh && skip "remote MDS with nodsh"
9253         remote_servers ||
9254                 skip "useless for local single node setup"
9255
9256         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9257                 [ "$PROT" != "tcp" ] && continue
9258                 RPORT=$(echo $REMOTE | cut -d: -f2)
9259                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9260
9261                 rc=0
9262                 LPORT=`echo $LOCAL | cut -d: -f2`
9263                 if [ $LPORT -ge 1024 ]; then
9264                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9265                         netstat -tna
9266                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9267                 fi
9268         done
9269         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9270 }
9271 run_test 100 "check local port using privileged port ==========="
9272
9273 function get_named_value()
9274 {
9275     local tag
9276
9277     tag=$1
9278     while read ;do
9279         line=$REPLY
9280         case $line in
9281         $tag*)
9282             echo $line | sed "s/^$tag[ ]*//"
9283             break
9284             ;;
9285         esac
9286     done
9287 }
9288
9289 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9290                    awk '/^max_cached_mb/ { print $2 }')
9291
9292 cleanup_101a() {
9293         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9294         trap 0
9295 }
9296
9297 test_101a() {
9298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9299
9300         local s
9301         local discard
9302         local nreads=10000
9303         local cache_limit=32
9304
9305         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9306         trap cleanup_101a EXIT
9307         $LCTL set_param -n llite.*.read_ahead_stats 0
9308         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9309
9310         #
9311         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9312         #
9313         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9314         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9315
9316         discard=0
9317         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9318                 get_named_value 'read but discarded' | cut -d" " -f1); do
9319                         discard=$(($discard + $s))
9320         done
9321         cleanup_101a
9322
9323         $LCTL get_param osc.*-osc*.rpc_stats
9324         $LCTL get_param llite.*.read_ahead_stats
9325
9326         # Discard is generally zero, but sometimes a few random reads line up
9327         # and trigger larger readahead, which is wasted & leads to discards.
9328         if [[ $(($discard)) -gt $nreads ]]; then
9329                 error "too many ($discard) discarded pages"
9330         fi
9331         rm -f $DIR/$tfile || true
9332 }
9333 run_test 101a "check read-ahead for random reads"
9334
9335 setup_test101bc() {
9336         test_mkdir $DIR/$tdir
9337         local ssize=$1
9338         local FILE_LENGTH=$2
9339         STRIPE_OFFSET=0
9340
9341         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9342
9343         local list=$(comma_list $(osts_nodes))
9344         set_osd_param $list '' read_cache_enable 0
9345         set_osd_param $list '' writethrough_cache_enable 0
9346
9347         trap cleanup_test101bc EXIT
9348         # prepare the read-ahead file
9349         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9350
9351         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9352                                 count=$FILE_SIZE_MB 2> /dev/null
9353
9354 }
9355
9356 cleanup_test101bc() {
9357         trap 0
9358         rm -rf $DIR/$tdir
9359         rm -f $DIR/$tfile
9360
9361         local list=$(comma_list $(osts_nodes))
9362         set_osd_param $list '' read_cache_enable 1
9363         set_osd_param $list '' writethrough_cache_enable 1
9364 }
9365
9366 calc_total() {
9367         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9368 }
9369
9370 ra_check_101() {
9371         local READ_SIZE=$1
9372         local STRIPE_SIZE=$2
9373         local FILE_LENGTH=$3
9374         local RA_INC=1048576
9375         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9376         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9377                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9378         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9379                         get_named_value 'read but discarded' |
9380                         cut -d" " -f1 | calc_total)
9381         if [[ $DISCARD -gt $discard_limit ]]; then
9382                 $LCTL get_param llite.*.read_ahead_stats
9383                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9384         else
9385                 echo "Read-ahead success for size ${READ_SIZE}"
9386         fi
9387 }
9388
9389 test_101b() {
9390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9391         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9392
9393         local STRIPE_SIZE=1048576
9394         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9395
9396         if [ $SLOW == "yes" ]; then
9397                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9398         else
9399                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9400         fi
9401
9402         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9403
9404         # prepare the read-ahead file
9405         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9406         cancel_lru_locks osc
9407         for BIDX in 2 4 8 16 32 64 128 256
9408         do
9409                 local BSIZE=$((BIDX*4096))
9410                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9411                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9412                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9413                 $LCTL set_param -n llite.*.read_ahead_stats 0
9414                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9415                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9416                 cancel_lru_locks osc
9417                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9418         done
9419         cleanup_test101bc
9420         true
9421 }
9422 run_test 101b "check stride-io mode read-ahead ================="
9423
9424 test_101c() {
9425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9426
9427         local STRIPE_SIZE=1048576
9428         local FILE_LENGTH=$((STRIPE_SIZE*100))
9429         local nreads=10000
9430         local rsize=65536
9431         local osc_rpc_stats
9432
9433         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9434
9435         cancel_lru_locks osc
9436         $LCTL set_param osc.*.rpc_stats 0
9437         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9438         $LCTL get_param osc.*.rpc_stats
9439         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9440                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9441                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9442                 local size
9443
9444                 if [ $lines -le 20 ]; then
9445                         echo "continue debug"
9446                         continue
9447                 fi
9448                 for size in 1 2 4 8; do
9449                         local rpc=$(echo "$stats" |
9450                                     awk '($1 == "'$size':") {print $2; exit; }')
9451                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9452                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9453                 done
9454                 echo "$osc_rpc_stats check passed!"
9455         done
9456         cleanup_test101bc
9457         true
9458 }
9459 run_test 101c "check stripe_size aligned read-ahead ================="
9460
9461 test_101d() {
9462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9463
9464         local file=$DIR/$tfile
9465         local sz_MB=${FILESIZE_101d:-80}
9466         local ra_MB=${READAHEAD_MB:-40}
9467
9468         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9469         [ $free_MB -lt $sz_MB ] &&
9470                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9471
9472         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9473         $LFS setstripe -c -1 $file || error "setstripe failed"
9474
9475         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9476         echo Cancel LRU locks on lustre client to flush the client cache
9477         cancel_lru_locks osc
9478
9479         echo Disable read-ahead
9480         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9481         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9482         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9483         $LCTL get_param -n llite.*.max_read_ahead_mb
9484
9485         echo "Reading the test file $file with read-ahead disabled"
9486         local sz_KB=$((sz_MB * 1024 / 4))
9487         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9488         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9489         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9490                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9491
9492         echo "Cancel LRU locks on lustre client to flush the client cache"
9493         cancel_lru_locks osc
9494         echo Enable read-ahead with ${ra_MB}MB
9495         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9496
9497         echo "Reading the test file $file with read-ahead enabled"
9498         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9499                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9500
9501         echo "read-ahead disabled time read $raOFF"
9502         echo "read-ahead enabled time read $raON"
9503
9504         rm -f $file
9505         wait_delete_completed
9506
9507         # use awk for this check instead of bash because it handles decimals
9508         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9509                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9510 }
9511 run_test 101d "file read with and without read-ahead enabled"
9512
9513 test_101e() {
9514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9515
9516         local file=$DIR/$tfile
9517         local size_KB=500  #KB
9518         local count=100
9519         local bsize=1024
9520
9521         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9522         local need_KB=$((count * size_KB))
9523         [[ $free_KB -le $need_KB ]] &&
9524                 skip_env "Need free space $need_KB, have $free_KB"
9525
9526         echo "Creating $count ${size_KB}K test files"
9527         for ((i = 0; i < $count; i++)); do
9528                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9529         done
9530
9531         echo "Cancel LRU locks on lustre client to flush the client cache"
9532         cancel_lru_locks $OSC
9533
9534         echo "Reset readahead stats"
9535         $LCTL set_param -n llite.*.read_ahead_stats 0
9536
9537         for ((i = 0; i < $count; i++)); do
9538                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9539         done
9540
9541         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9542                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9543
9544         for ((i = 0; i < $count; i++)); do
9545                 rm -rf $file.$i 2>/dev/null
9546         done
9547
9548         #10000 means 20% reads are missing in readahead
9549         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9550 }
9551 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9552
9553 test_101f() {
9554         which iozone || skip_env "no iozone installed"
9555
9556         local old_debug=$($LCTL get_param debug)
9557         old_debug=${old_debug#*=}
9558         $LCTL set_param debug="reada mmap"
9559
9560         # create a test file
9561         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9562
9563         echo Cancel LRU locks on lustre client to flush the client cache
9564         cancel_lru_locks osc
9565
9566         echo Reset readahead stats
9567         $LCTL set_param -n llite.*.read_ahead_stats 0
9568
9569         echo mmap read the file with small block size
9570         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9571                 > /dev/null 2>&1
9572
9573         echo checking missing pages
9574         $LCTL get_param llite.*.read_ahead_stats
9575         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9576                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9577
9578         $LCTL set_param debug="$old_debug"
9579         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9580         rm -f $DIR/$tfile
9581 }
9582 run_test 101f "check mmap read performance"
9583
9584 test_101g_brw_size_test() {
9585         local mb=$1
9586         local pages=$((mb * 1048576 / PAGE_SIZE))
9587         local file=$DIR/$tfile
9588
9589         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9590                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9591         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9592                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9593                         return 2
9594         done
9595
9596         stack_trap "rm -f $file" EXIT
9597         $LCTL set_param -n osc.*.rpc_stats=0
9598
9599         # 10 RPCs should be enough for the test
9600         local count=10
9601         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9602                 { error "dd write ${mb} MB blocks failed"; return 3; }
9603         cancel_lru_locks osc
9604         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9605                 { error "dd write ${mb} MB blocks failed"; return 4; }
9606
9607         # calculate number of full-sized read and write RPCs
9608         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9609                 sed -n '/pages per rpc/,/^$/p' |
9610                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9611                 END { print reads,writes }'))
9612         # allow one extra full-sized read RPC for async readahead
9613         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9614                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9615         [[ ${rpcs[1]} == $count ]] ||
9616                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9617 }
9618
9619 test_101g() {
9620         remote_ost_nodsh && skip "remote OST with nodsh"
9621
9622         local rpcs
9623         local osts=$(get_facets OST)
9624         local list=$(comma_list $(osts_nodes))
9625         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9626         local brw_size="obdfilter.*.brw_size"
9627
9628         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9629
9630         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9631
9632         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9633                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9634                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9635            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9636                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9637                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9638
9639                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9640                         suffix="M"
9641
9642                 if [[ $orig_mb -lt 16 ]]; then
9643                         save_lustre_params $osts "$brw_size" > $p
9644                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9645                                 error "set 16MB RPC size failed"
9646
9647                         echo "remount client to enable new RPC size"
9648                         remount_client $MOUNT || error "remount_client failed"
9649                 fi
9650
9651                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9652                 # should be able to set brw_size=12, but no rpc_stats for that
9653                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9654         fi
9655
9656         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9657
9658         if [[ $orig_mb -lt 16 ]]; then
9659                 restore_lustre_params < $p
9660                 remount_client $MOUNT || error "remount_client restore failed"
9661         fi
9662
9663         rm -f $p $DIR/$tfile
9664 }
9665 run_test 101g "Big bulk(4/16 MiB) readahead"
9666
9667 test_101h() {
9668         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9669
9670         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9671                 error "dd 70M file failed"
9672         echo Cancel LRU locks on lustre client to flush the client cache
9673         cancel_lru_locks osc
9674
9675         echo "Reset readahead stats"
9676         $LCTL set_param -n llite.*.read_ahead_stats 0
9677
9678         echo "Read 10M of data but cross 64M bundary"
9679         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9680         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9681                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9682         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9683         rm -f $p $DIR/$tfile
9684 }
9685 run_test 101h "Readahead should cover current read window"
9686
9687 test_101i() {
9688         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9689                 error "dd 10M file failed"
9690
9691         local max_per_file_mb=$($LCTL get_param -n \
9692                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9693         cancel_lru_locks osc
9694         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9695         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9696                 error "set max_read_ahead_per_file_mb to 1 failed"
9697
9698         echo "Reset readahead stats"
9699         $LCTL set_param llite.*.read_ahead_stats=0
9700
9701         dd if=$DIR/$tfile of=/dev/null bs=2M
9702
9703         $LCTL get_param llite.*.read_ahead_stats
9704         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9705                      awk '/misses/ { print $2 }')
9706         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9707         rm -f $DIR/$tfile
9708 }
9709 run_test 101i "allow current readahead to exceed reservation"
9710
9711 test_101j() {
9712         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9713                 error "setstripe $DIR/$tfile failed"
9714         local file_size=$((1048576 * 16))
9715         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9716         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9717
9718         echo Disable read-ahead
9719         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9720
9721         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9722         for blk in $PAGE_SIZE 1048576 $file_size; do
9723                 cancel_lru_locks osc
9724                 echo "Reset readahead stats"
9725                 $LCTL set_param -n llite.*.read_ahead_stats=0
9726                 local count=$(($file_size / $blk))
9727                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9728                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9729                              get_named_value 'failed to fast read' |
9730                              cut -d" " -f1 | calc_total)
9731                 $LCTL get_param -n llite.*.read_ahead_stats
9732                 [ $miss -eq $count ] || error "expected $count got $miss"
9733         done
9734
9735         rm -f $p $DIR/$tfile
9736 }
9737 run_test 101j "A complete read block should be submitted when no RA"
9738
9739 setup_test102() {
9740         test_mkdir $DIR/$tdir
9741         chown $RUNAS_ID $DIR/$tdir
9742         STRIPE_SIZE=65536
9743         STRIPE_OFFSET=1
9744         STRIPE_COUNT=$OSTCOUNT
9745         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9746
9747         trap cleanup_test102 EXIT
9748         cd $DIR
9749         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9750         cd $DIR/$tdir
9751         for num in 1 2 3 4; do
9752                 for count in $(seq 1 $STRIPE_COUNT); do
9753                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9754                                 local size=`expr $STRIPE_SIZE \* $num`
9755                                 local file=file"$num-$idx-$count"
9756                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9757                         done
9758                 done
9759         done
9760
9761         cd $DIR
9762         $1 tar cf $TMP/f102.tar $tdir --xattrs
9763 }
9764
9765 cleanup_test102() {
9766         trap 0
9767         rm -f $TMP/f102.tar
9768         rm -rf $DIR/d0.sanity/d102
9769 }
9770
9771 test_102a() {
9772         [ "$UID" != 0 ] && skip "must run as root"
9773         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9774                 skip_env "must have user_xattr"
9775
9776         [ -z "$(which setfattr 2>/dev/null)" ] &&
9777                 skip_env "could not find setfattr"
9778
9779         local testfile=$DIR/$tfile
9780
9781         touch $testfile
9782         echo "set/get xattr..."
9783         setfattr -n trusted.name1 -v value1 $testfile ||
9784                 error "setfattr -n trusted.name1=value1 $testfile failed"
9785         getfattr -n trusted.name1 $testfile 2> /dev/null |
9786           grep "trusted.name1=.value1" ||
9787                 error "$testfile missing trusted.name1=value1"
9788
9789         setfattr -n user.author1 -v author1 $testfile ||
9790                 error "setfattr -n user.author1=author1 $testfile failed"
9791         getfattr -n user.author1 $testfile 2> /dev/null |
9792           grep "user.author1=.author1" ||
9793                 error "$testfile missing trusted.author1=author1"
9794
9795         echo "listxattr..."
9796         setfattr -n trusted.name2 -v value2 $testfile ||
9797                 error "$testfile unable to set trusted.name2"
9798         setfattr -n trusted.name3 -v value3 $testfile ||
9799                 error "$testfile unable to set trusted.name3"
9800         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9801             grep "trusted.name" | wc -l) -eq 3 ] ||
9802                 error "$testfile missing 3 trusted.name xattrs"
9803
9804         setfattr -n user.author2 -v author2 $testfile ||
9805                 error "$testfile unable to set user.author2"
9806         setfattr -n user.author3 -v author3 $testfile ||
9807                 error "$testfile unable to set user.author3"
9808         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9809             grep "user.author" | wc -l) -eq 3 ] ||
9810                 error "$testfile missing 3 user.author xattrs"
9811
9812         echo "remove xattr..."
9813         setfattr -x trusted.name1 $testfile ||
9814                 error "$testfile error deleting trusted.name1"
9815         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9816                 error "$testfile did not delete trusted.name1 xattr"
9817
9818         setfattr -x user.author1 $testfile ||
9819                 error "$testfile error deleting user.author1"
9820         echo "set lustre special xattr ..."
9821         $LFS setstripe -c1 $testfile
9822         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9823                 awk -F "=" '/trusted.lov/ { print $2 }' )
9824         setfattr -n "trusted.lov" -v $lovea $testfile ||
9825                 error "$testfile doesn't ignore setting trusted.lov again"
9826         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9827                 error "$testfile allow setting invalid trusted.lov"
9828         rm -f $testfile
9829 }
9830 run_test 102a "user xattr test =================================="
9831
9832 check_102b_layout() {
9833         local layout="$*"
9834         local testfile=$DIR/$tfile
9835
9836         echo "test layout '$layout'"
9837         $LFS setstripe $layout $testfile || error "setstripe failed"
9838         $LFS getstripe -y $testfile
9839
9840         echo "get/set/list trusted.lov xattr ..." # b=10930
9841         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9842         [[ "$value" =~ "trusted.lov" ]] ||
9843                 error "can't get trusted.lov from $testfile"
9844         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9845                 error "getstripe failed"
9846
9847         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9848
9849         value=$(cut -d= -f2 <<<$value)
9850         # LU-13168: truncated xattr should fail if short lov_user_md header
9851         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9852                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9853         for len in $lens; do
9854                 echo "setfattr $len $testfile.2"
9855                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9856                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9857         done
9858         local stripe_size=$($LFS getstripe -S $testfile.2)
9859         local stripe_count=$($LFS getstripe -c $testfile.2)
9860         [[ $stripe_size -eq 65536 ]] ||
9861                 error "stripe size $stripe_size != 65536"
9862         [[ $stripe_count -eq $stripe_count_orig ]] ||
9863                 error "stripe count $stripe_count != $stripe_count_orig"
9864         rm $testfile $testfile.2
9865 }
9866
9867 test_102b() {
9868         [ -z "$(which setfattr 2>/dev/null)" ] &&
9869                 skip_env "could not find setfattr"
9870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9871
9872         # check plain layout
9873         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9874
9875         # and also check composite layout
9876         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9877
9878 }
9879 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9880
9881 test_102c() {
9882         [ -z "$(which setfattr 2>/dev/null)" ] &&
9883                 skip_env "could not find setfattr"
9884         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9885
9886         # b10930: get/set/list lustre.lov xattr
9887         echo "get/set/list lustre.lov xattr ..."
9888         test_mkdir $DIR/$tdir
9889         chown $RUNAS_ID $DIR/$tdir
9890         local testfile=$DIR/$tdir/$tfile
9891         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9892                 error "setstripe failed"
9893         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9894                 error "getstripe failed"
9895         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9896         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9897
9898         local testfile2=${testfile}2
9899         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9900                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9901
9902         $RUNAS $MCREATE $testfile2
9903         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9904         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9905         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9906         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9907         [ $stripe_count -eq $STRIPECOUNT ] ||
9908                 error "stripe count $stripe_count != $STRIPECOUNT"
9909 }
9910 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9911
9912 compare_stripe_info1() {
9913         local stripe_index_all_zero=true
9914
9915         for num in 1 2 3 4; do
9916                 for count in $(seq 1 $STRIPE_COUNT); do
9917                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9918                                 local size=$((STRIPE_SIZE * num))
9919                                 local file=file"$num-$offset-$count"
9920                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9921                                 [[ $stripe_size -ne $size ]] &&
9922                                     error "$file: size $stripe_size != $size"
9923                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9924                                 # allow fewer stripes to be created, ORI-601
9925                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9926                                     error "$file: count $stripe_count != $count"
9927                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9928                                 [[ $stripe_index -ne 0 ]] &&
9929                                         stripe_index_all_zero=false
9930                         done
9931                 done
9932         done
9933         $stripe_index_all_zero &&
9934                 error "all files are being extracted starting from OST index 0"
9935         return 0
9936 }
9937
9938 have_xattrs_include() {
9939         tar --help | grep -q xattrs-include &&
9940                 echo --xattrs-include="lustre.*"
9941 }
9942
9943 test_102d() {
9944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9945         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9946
9947         XINC=$(have_xattrs_include)
9948         setup_test102
9949         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9950         cd $DIR/$tdir/$tdir
9951         compare_stripe_info1
9952 }
9953 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9954
9955 test_102f() {
9956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9957         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9958
9959         XINC=$(have_xattrs_include)
9960         setup_test102
9961         test_mkdir $DIR/$tdir.restore
9962         cd $DIR
9963         tar cf - --xattrs $tdir | tar xf - \
9964                 -C $DIR/$tdir.restore --xattrs $XINC
9965         cd $DIR/$tdir.restore/$tdir
9966         compare_stripe_info1
9967 }
9968 run_test 102f "tar copy files, not keep osts"
9969
9970 grow_xattr() {
9971         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9972                 skip "must have user_xattr"
9973         [ -z "$(which setfattr 2>/dev/null)" ] &&
9974                 skip_env "could not find setfattr"
9975         [ -z "$(which getfattr 2>/dev/null)" ] &&
9976                 skip_env "could not find getfattr"
9977
9978         local xsize=${1:-1024}  # in bytes
9979         local file=$DIR/$tfile
9980         local value="$(generate_string $xsize)"
9981         local xbig=trusted.big
9982         local toobig=$2
9983
9984         touch $file
9985         log "save $xbig on $file"
9986         if [ -z "$toobig" ]
9987         then
9988                 setfattr -n $xbig -v $value $file ||
9989                         error "saving $xbig on $file failed"
9990         else
9991                 setfattr -n $xbig -v $value $file &&
9992                         error "saving $xbig on $file succeeded"
9993                 return 0
9994         fi
9995
9996         local orig=$(get_xattr_value $xbig $file)
9997         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9998
9999         local xsml=trusted.sml
10000         log "save $xsml on $file"
10001         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10002
10003         local new=$(get_xattr_value $xbig $file)
10004         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10005
10006         log "grow $xsml on $file"
10007         setfattr -n $xsml -v "$value" $file ||
10008                 error "growing $xsml on $file failed"
10009
10010         new=$(get_xattr_value $xbig $file)
10011         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10012         log "$xbig still valid after growing $xsml"
10013
10014         rm -f $file
10015 }
10016
10017 test_102h() { # bug 15777
10018         grow_xattr 1024
10019 }
10020 run_test 102h "grow xattr from inside inode to external block"
10021
10022 test_102ha() {
10023         large_xattr_enabled || skip_env "ea_inode feature disabled"
10024
10025         echo "setting xattr of max xattr size: $(max_xattr_size)"
10026         grow_xattr $(max_xattr_size)
10027
10028         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10029         echo "This should fail:"
10030         grow_xattr $(($(max_xattr_size) + 10)) 1
10031 }
10032 run_test 102ha "grow xattr from inside inode to external inode"
10033
10034 test_102i() { # bug 17038
10035         [ -z "$(which getfattr 2>/dev/null)" ] &&
10036                 skip "could not find getfattr"
10037
10038         touch $DIR/$tfile
10039         ln -s $DIR/$tfile $DIR/${tfile}link
10040         getfattr -n trusted.lov $DIR/$tfile ||
10041                 error "lgetxattr on $DIR/$tfile failed"
10042         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10043                 grep -i "no such attr" ||
10044                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10045         rm -f $DIR/$tfile $DIR/${tfile}link
10046 }
10047 run_test 102i "lgetxattr test on symbolic link ============"
10048
10049 test_102j() {
10050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10051         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10052
10053         XINC=$(have_xattrs_include)
10054         setup_test102 "$RUNAS"
10055         chown $RUNAS_ID $DIR/$tdir
10056         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10057         cd $DIR/$tdir/$tdir
10058         compare_stripe_info1 "$RUNAS"
10059 }
10060 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10061
10062 test_102k() {
10063         [ -z "$(which setfattr 2>/dev/null)" ] &&
10064                 skip "could not find setfattr"
10065
10066         touch $DIR/$tfile
10067         # b22187 just check that does not crash for regular file.
10068         setfattr -n trusted.lov $DIR/$tfile
10069         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10070         local test_kdir=$DIR/$tdir
10071         test_mkdir $test_kdir
10072         local default_size=$($LFS getstripe -S $test_kdir)
10073         local default_count=$($LFS getstripe -c $test_kdir)
10074         local default_offset=$($LFS getstripe -i $test_kdir)
10075         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10076                 error 'dir setstripe failed'
10077         setfattr -n trusted.lov $test_kdir
10078         local stripe_size=$($LFS getstripe -S $test_kdir)
10079         local stripe_count=$($LFS getstripe -c $test_kdir)
10080         local stripe_offset=$($LFS getstripe -i $test_kdir)
10081         [ $stripe_size -eq $default_size ] ||
10082                 error "stripe size $stripe_size != $default_size"
10083         [ $stripe_count -eq $default_count ] ||
10084                 error "stripe count $stripe_count != $default_count"
10085         [ $stripe_offset -eq $default_offset ] ||
10086                 error "stripe offset $stripe_offset != $default_offset"
10087         rm -rf $DIR/$tfile $test_kdir
10088 }
10089 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10090
10091 test_102l() {
10092         [ -z "$(which getfattr 2>/dev/null)" ] &&
10093                 skip "could not find getfattr"
10094
10095         # LU-532 trusted. xattr is invisible to non-root
10096         local testfile=$DIR/$tfile
10097
10098         touch $testfile
10099
10100         echo "listxattr as user..."
10101         chown $RUNAS_ID $testfile
10102         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10103             grep -q "trusted" &&
10104                 error "$testfile trusted xattrs are user visible"
10105
10106         return 0;
10107 }
10108 run_test 102l "listxattr size test =================================="
10109
10110 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10111         local path=$DIR/$tfile
10112         touch $path
10113
10114         listxattr_size_check $path || error "listattr_size_check $path failed"
10115 }
10116 run_test 102m "Ensure listxattr fails on small bufffer ========"
10117
10118 cleanup_test102
10119
10120 getxattr() { # getxattr path name
10121         # Return the base64 encoding of the value of xattr name on path.
10122         local path=$1
10123         local name=$2
10124
10125         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10126         # file: $path
10127         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10128         #
10129         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10130
10131         getfattr --absolute-names --encoding=base64 --name=$name $path |
10132                 awk -F= -v name=$name '$1 == name {
10133                         print substr($0, index($0, "=") + 1);
10134         }'
10135 }
10136
10137 test_102n() { # LU-4101 mdt: protect internal xattrs
10138         [ -z "$(which setfattr 2>/dev/null)" ] &&
10139                 skip "could not find setfattr"
10140         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10141         then
10142                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10143         fi
10144
10145         local file0=$DIR/$tfile.0
10146         local file1=$DIR/$tfile.1
10147         local xattr0=$TMP/$tfile.0
10148         local xattr1=$TMP/$tfile.1
10149         local namelist="lov lma lmv link fid version som hsm"
10150         local name
10151         local value
10152
10153         rm -rf $file0 $file1 $xattr0 $xattr1
10154         touch $file0 $file1
10155
10156         # Get 'before' xattrs of $file1.
10157         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10158
10159         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10160                 namelist+=" lfsck_namespace"
10161         for name in $namelist; do
10162                 # Try to copy xattr from $file0 to $file1.
10163                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10164
10165                 setfattr --name=trusted.$name --value="$value" $file1 ||
10166                         error "setxattr 'trusted.$name' failed"
10167
10168                 # Try to set a garbage xattr.
10169                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10170
10171                 if [[ x$name == "xlov" ]]; then
10172                         setfattr --name=trusted.lov --value="$value" $file1 &&
10173                         error "setxattr invalid 'trusted.lov' success"
10174                 else
10175                         setfattr --name=trusted.$name --value="$value" $file1 ||
10176                                 error "setxattr invalid 'trusted.$name' failed"
10177                 fi
10178
10179                 # Try to remove the xattr from $file1. We don't care if this
10180                 # appears to succeed or fail, we just don't want there to be
10181                 # any changes or crashes.
10182                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10183         done
10184
10185         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10186         then
10187                 name="lfsck_ns"
10188                 # Try to copy xattr from $file0 to $file1.
10189                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10190
10191                 setfattr --name=trusted.$name --value="$value" $file1 ||
10192                         error "setxattr 'trusted.$name' failed"
10193
10194                 # Try to set a garbage xattr.
10195                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10196
10197                 setfattr --name=trusted.$name --value="$value" $file1 ||
10198                         error "setxattr 'trusted.$name' failed"
10199
10200                 # Try to remove the xattr from $file1. We don't care if this
10201                 # appears to succeed or fail, we just don't want there to be
10202                 # any changes or crashes.
10203                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10204         fi
10205
10206         # Get 'after' xattrs of file1.
10207         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10208
10209         if ! diff $xattr0 $xattr1; then
10210                 error "before and after xattrs of '$file1' differ"
10211         fi
10212
10213         rm -rf $file0 $file1 $xattr0 $xattr1
10214
10215         return 0
10216 }
10217 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10218
10219 test_102p() { # LU-4703 setxattr did not check ownership
10220         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10221                 skip "MDS needs to be at least 2.5.56"
10222
10223         local testfile=$DIR/$tfile
10224
10225         touch $testfile
10226
10227         echo "setfacl as user..."
10228         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10229         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10230
10231         echo "setfattr as user..."
10232         setfacl -m "u:$RUNAS_ID:---" $testfile
10233         $RUNAS setfattr -x system.posix_acl_access $testfile
10234         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10235 }
10236 run_test 102p "check setxattr(2) correctly fails without permission"
10237
10238 test_102q() {
10239         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10240                 skip "MDS needs to be at least 2.6.92"
10241
10242         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10243 }
10244 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10245
10246 test_102r() {
10247         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10248                 skip "MDS needs to be at least 2.6.93"
10249
10250         touch $DIR/$tfile || error "touch"
10251         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10252         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10253         rm $DIR/$tfile || error "rm"
10254
10255         #normal directory
10256         mkdir -p $DIR/$tdir || error "mkdir"
10257         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10258         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10259         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10260                 error "$testfile error deleting user.author1"
10261         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10262                 grep "user.$(basename $tdir)" &&
10263                 error "$tdir did not delete user.$(basename $tdir)"
10264         rmdir $DIR/$tdir || error "rmdir"
10265
10266         #striped directory
10267         test_mkdir $DIR/$tdir
10268         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10269         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10270         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10271                 error "$testfile error deleting user.author1"
10272         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10273                 grep "user.$(basename $tdir)" &&
10274                 error "$tdir did not delete user.$(basename $tdir)"
10275         rmdir $DIR/$tdir || error "rm striped dir"
10276 }
10277 run_test 102r "set EAs with empty values"
10278
10279 test_102s() {
10280         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10281                 skip "MDS needs to be at least 2.11.52"
10282
10283         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10284
10285         save_lustre_params client "llite.*.xattr_cache" > $save
10286
10287         for cache in 0 1; do
10288                 lctl set_param llite.*.xattr_cache=$cache
10289
10290                 rm -f $DIR/$tfile
10291                 touch $DIR/$tfile || error "touch"
10292                 for prefix in lustre security system trusted user; do
10293                         # Note getxattr() may fail with 'Operation not
10294                         # supported' or 'No such attribute' depending
10295                         # on prefix and cache.
10296                         getfattr -n $prefix.n102s $DIR/$tfile &&
10297                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10298                 done
10299         done
10300
10301         restore_lustre_params < $save
10302 }
10303 run_test 102s "getting nonexistent xattrs should fail"
10304
10305 test_102t() {
10306         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10307                 skip "MDS needs to be at least 2.11.52"
10308
10309         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10310
10311         save_lustre_params client "llite.*.xattr_cache" > $save
10312
10313         for cache in 0 1; do
10314                 lctl set_param llite.*.xattr_cache=$cache
10315
10316                 for buf_size in 0 256; do
10317                         rm -f $DIR/$tfile
10318                         touch $DIR/$tfile || error "touch"
10319                         setfattr -n user.multiop $DIR/$tfile
10320                         $MULTIOP $DIR/$tfile oa$buf_size ||
10321                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10322                 done
10323         done
10324
10325         restore_lustre_params < $save
10326 }
10327 run_test 102t "zero length xattr values handled correctly"
10328
10329 run_acl_subtest()
10330 {
10331     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10332     return $?
10333 }
10334
10335 test_103a() {
10336         [ "$UID" != 0 ] && skip "must run as root"
10337         $GSS && skip_env "could not run under gss"
10338         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10339                 skip_env "must have acl enabled"
10340         [ -z "$(which setfacl 2>/dev/null)" ] &&
10341                 skip_env "could not find setfacl"
10342         remote_mds_nodsh && skip "remote MDS with nodsh"
10343
10344         gpasswd -a daemon bin                           # LU-5641
10345         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10346
10347         declare -a identity_old
10348
10349         for num in $(seq $MDSCOUNT); do
10350                 switch_identity $num true || identity_old[$num]=$?
10351         done
10352
10353         SAVE_UMASK=$(umask)
10354         umask 0022
10355         mkdir -p $DIR/$tdir
10356         cd $DIR/$tdir
10357
10358         echo "performing cp ..."
10359         run_acl_subtest cp || error "run_acl_subtest cp failed"
10360         echo "performing getfacl-noacl..."
10361         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10362         echo "performing misc..."
10363         run_acl_subtest misc || error  "misc test failed"
10364         echo "performing permissions..."
10365         run_acl_subtest permissions || error "permissions failed"
10366         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10367         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10368                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10369                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10370         then
10371                 echo "performing permissions xattr..."
10372                 run_acl_subtest permissions_xattr ||
10373                         error "permissions_xattr failed"
10374         fi
10375         echo "performing setfacl..."
10376         run_acl_subtest setfacl || error  "setfacl test failed"
10377
10378         # inheritance test got from HP
10379         echo "performing inheritance..."
10380         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10381         chmod +x make-tree || error "chmod +x failed"
10382         run_acl_subtest inheritance || error "inheritance test failed"
10383         rm -f make-tree
10384
10385         echo "LU-974 ignore umask when acl is enabled..."
10386         run_acl_subtest 974 || error "LU-974 umask test failed"
10387         if [ $MDSCOUNT -ge 2 ]; then
10388                 run_acl_subtest 974_remote ||
10389                         error "LU-974 umask test failed under remote dir"
10390         fi
10391
10392         echo "LU-2561 newly created file is same size as directory..."
10393         if [ "$mds1_FSTYPE" != "zfs" ]; then
10394                 run_acl_subtest 2561 || error "LU-2561 test failed"
10395         else
10396                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10397         fi
10398
10399         run_acl_subtest 4924 || error "LU-4924 test failed"
10400
10401         cd $SAVE_PWD
10402         umask $SAVE_UMASK
10403
10404         for num in $(seq $MDSCOUNT); do
10405                 if [ "${identity_old[$num]}" = 1 ]; then
10406                         switch_identity $num false || identity_old[$num]=$?
10407                 fi
10408         done
10409 }
10410 run_test 103a "acl test"
10411
10412 test_103b() {
10413         declare -a pids
10414         local U
10415
10416         for U in {0..511}; do
10417                 {
10418                 local O=$(printf "%04o" $U)
10419
10420                 umask $(printf "%04o" $((511 ^ $O)))
10421                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10422                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10423
10424                 (( $S == ($O & 0666) )) ||
10425                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10426
10427                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10428                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10429                 (( $S == ($O & 0666) )) ||
10430                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10431
10432                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10433                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10434                 (( $S == ($O & 0666) )) ||
10435                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10436                 rm -f $DIR/$tfile.[smp]$0
10437                 } &
10438                 local pid=$!
10439
10440                 # limit the concurrently running threads to 64. LU-11878
10441                 local idx=$((U % 64))
10442                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10443                 pids[idx]=$pid
10444         done
10445         wait
10446 }
10447 run_test 103b "umask lfs setstripe"
10448
10449 test_103c() {
10450         mkdir -p $DIR/$tdir
10451         cp -rp $DIR/$tdir $DIR/$tdir.bak
10452
10453         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10454                 error "$DIR/$tdir shouldn't contain default ACL"
10455         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10456                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10457         true
10458 }
10459 run_test 103c "'cp -rp' won't set empty acl"
10460
10461 test_104a() {
10462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10463
10464         touch $DIR/$tfile
10465         lfs df || error "lfs df failed"
10466         lfs df -ih || error "lfs df -ih failed"
10467         lfs df -h $DIR || error "lfs df -h $DIR failed"
10468         lfs df -i $DIR || error "lfs df -i $DIR failed"
10469         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10470         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10471
10472         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10473         lctl --device %$OSC deactivate
10474         lfs df || error "lfs df with deactivated OSC failed"
10475         lctl --device %$OSC activate
10476         # wait the osc back to normal
10477         wait_osc_import_ready client ost
10478
10479         lfs df || error "lfs df with reactivated OSC failed"
10480         rm -f $DIR/$tfile
10481 }
10482 run_test 104a "lfs df [-ih] [path] test ========================="
10483
10484 test_104b() {
10485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10486         [ $RUNAS_ID -eq $UID ] &&
10487                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10488
10489         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10490                         grep "Permission denied" | wc -l)))
10491         if [ $denied_cnt -ne 0 ]; then
10492                 error "lfs check servers test failed"
10493         fi
10494 }
10495 run_test 104b "$RUNAS lfs check servers test ===================="
10496
10497 test_105a() {
10498         # doesn't work on 2.4 kernels
10499         touch $DIR/$tfile
10500         if $(flock_is_enabled); then
10501                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10502         else
10503                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10504         fi
10505         rm -f $DIR/$tfile
10506 }
10507 run_test 105a "flock when mounted without -o flock test ========"
10508
10509 test_105b() {
10510         touch $DIR/$tfile
10511         if $(flock_is_enabled); then
10512                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10513         else
10514                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10515         fi
10516         rm -f $DIR/$tfile
10517 }
10518 run_test 105b "fcntl when mounted without -o flock test ========"
10519
10520 test_105c() {
10521         touch $DIR/$tfile
10522         if $(flock_is_enabled); then
10523                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10524         else
10525                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10526         fi
10527         rm -f $DIR/$tfile
10528 }
10529 run_test 105c "lockf when mounted without -o flock test"
10530
10531 test_105d() { # bug 15924
10532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10533
10534         test_mkdir $DIR/$tdir
10535         flock_is_enabled || skip_env "mount w/o flock enabled"
10536         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10537         $LCTL set_param fail_loc=0x80000315
10538         flocks_test 2 $DIR/$tdir
10539 }
10540 run_test 105d "flock race (should not freeze) ========"
10541
10542 test_105e() { # bug 22660 && 22040
10543         flock_is_enabled || skip_env "mount w/o flock enabled"
10544
10545         touch $DIR/$tfile
10546         flocks_test 3 $DIR/$tfile
10547 }
10548 run_test 105e "Two conflicting flocks from same process"
10549
10550 test_106() { #bug 10921
10551         test_mkdir $DIR/$tdir
10552         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10553         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10554 }
10555 run_test 106 "attempt exec of dir followed by chown of that dir"
10556
10557 test_107() {
10558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10559
10560         CDIR=`pwd`
10561         local file=core
10562
10563         cd $DIR
10564         rm -f $file
10565
10566         local save_pattern=$(sysctl -n kernel.core_pattern)
10567         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10568         sysctl -w kernel.core_pattern=$file
10569         sysctl -w kernel.core_uses_pid=0
10570
10571         ulimit -c unlimited
10572         sleep 60 &
10573         SLEEPPID=$!
10574
10575         sleep 1
10576
10577         kill -s 11 $SLEEPPID
10578         wait $SLEEPPID
10579         if [ -e $file ]; then
10580                 size=`stat -c%s $file`
10581                 [ $size -eq 0 ] && error "Fail to create core file $file"
10582         else
10583                 error "Fail to create core file $file"
10584         fi
10585         rm -f $file
10586         sysctl -w kernel.core_pattern=$save_pattern
10587         sysctl -w kernel.core_uses_pid=$save_uses_pid
10588         cd $CDIR
10589 }
10590 run_test 107 "Coredump on SIG"
10591
10592 test_110() {
10593         test_mkdir $DIR/$tdir
10594         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10595         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10596                 error "mkdir with 256 char should fail, but did not"
10597         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10598                 error "create with 255 char failed"
10599         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10600                 error "create with 256 char should fail, but did not"
10601
10602         ls -l $DIR/$tdir
10603         rm -rf $DIR/$tdir
10604 }
10605 run_test 110 "filename length checking"
10606
10607 #
10608 # Purpose: To verify dynamic thread (OSS) creation.
10609 #
10610 test_115() {
10611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10612         remote_ost_nodsh && skip "remote OST with nodsh"
10613
10614         # Lustre does not stop service threads once they are started.
10615         # Reset number of running threads to default.
10616         stopall
10617         setupall
10618
10619         local OSTIO_pre
10620         local save_params="$TMP/sanity-$TESTNAME.parameters"
10621
10622         # Get ll_ost_io count before I/O
10623         OSTIO_pre=$(do_facet ost1 \
10624                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10625         # Exit if lustre is not running (ll_ost_io not running).
10626         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10627
10628         echo "Starting with $OSTIO_pre threads"
10629         local thread_max=$((OSTIO_pre * 2))
10630         local rpc_in_flight=$((thread_max * 2))
10631         # Number of I/O Process proposed to be started.
10632         local nfiles
10633         local facets=$(get_facets OST)
10634
10635         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10636         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10637
10638         # Set in_flight to $rpc_in_flight
10639         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10640                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10641         nfiles=${rpc_in_flight}
10642         # Set ost thread_max to $thread_max
10643         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10644
10645         # 5 Minutes should be sufficient for max number of OSS
10646         # threads(thread_max) to be created.
10647         local timeout=300
10648
10649         # Start I/O.
10650         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10651         test_mkdir $DIR/$tdir
10652         for i in $(seq $nfiles); do
10653                 local file=$DIR/$tdir/${tfile}-$i
10654                 $LFS setstripe -c -1 -i 0 $file
10655                 ($WTL $file $timeout)&
10656         done
10657
10658         # I/O Started - Wait for thread_started to reach thread_max or report
10659         # error if thread_started is more than thread_max.
10660         echo "Waiting for thread_started to reach thread_max"
10661         local thread_started=0
10662         local end_time=$((SECONDS + timeout))
10663
10664         while [ $SECONDS -le $end_time ] ; do
10665                 echo -n "."
10666                 # Get ost i/o thread_started count.
10667                 thread_started=$(do_facet ost1 \
10668                         "$LCTL get_param \
10669                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10670                 # Break out if thread_started is equal/greater than thread_max
10671                 if [[ $thread_started -ge $thread_max ]]; then
10672                         echo ll_ost_io thread_started $thread_started, \
10673                                 equal/greater than thread_max $thread_max
10674                         break
10675                 fi
10676                 sleep 1
10677         done
10678
10679         # Cleanup - We have the numbers, Kill i/o jobs if running.
10680         jobcount=($(jobs -p))
10681         for i in $(seq 0 $((${#jobcount[@]}-1)))
10682         do
10683                 kill -9 ${jobcount[$i]}
10684                 if [ $? -ne 0 ] ; then
10685                         echo Warning: \
10686                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10687                 fi
10688         done
10689
10690         # Cleanup files left by WTL binary.
10691         for i in $(seq $nfiles); do
10692                 local file=$DIR/$tdir/${tfile}-$i
10693                 rm -rf $file
10694                 if [ $? -ne 0 ] ; then
10695                         echo "Warning: Failed to delete file $file"
10696                 fi
10697         done
10698
10699         restore_lustre_params <$save_params
10700         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10701
10702         # Error out if no new thread has started or Thread started is greater
10703         # than thread max.
10704         if [[ $thread_started -le $OSTIO_pre ||
10705                         $thread_started -gt $thread_max ]]; then
10706                 error "ll_ost_io: thread_started $thread_started" \
10707                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10708                       "No new thread started or thread started greater " \
10709                       "than thread_max."
10710         fi
10711 }
10712 run_test 115 "verify dynamic thread creation===================="
10713
10714 free_min_max () {
10715         wait_delete_completed
10716         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10717         echo "OST kbytes available: ${AVAIL[@]}"
10718         MAXV=${AVAIL[0]}
10719         MAXI=0
10720         MINV=${AVAIL[0]}
10721         MINI=0
10722         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10723                 #echo OST $i: ${AVAIL[i]}kb
10724                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10725                         MAXV=${AVAIL[i]}
10726                         MAXI=$i
10727                 fi
10728                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10729                         MINV=${AVAIL[i]}
10730                         MINI=$i
10731                 fi
10732         done
10733         echo "Min free space: OST $MINI: $MINV"
10734         echo "Max free space: OST $MAXI: $MAXV"
10735 }
10736
10737 test_116a() { # was previously test_116()
10738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10739         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10740         remote_mds_nodsh && skip "remote MDS with nodsh"
10741
10742         echo -n "Free space priority "
10743         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10744                 head -n1
10745         declare -a AVAIL
10746         free_min_max
10747
10748         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10749         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10750         trap simple_cleanup_common EXIT
10751
10752         # Check if we need to generate uneven OSTs
10753         test_mkdir -p $DIR/$tdir/OST${MINI}
10754         local FILL=$((MINV / 4))
10755         local DIFF=$((MAXV - MINV))
10756         local DIFF2=$((DIFF * 100 / MINV))
10757
10758         local threshold=$(do_facet $SINGLEMDS \
10759                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10760         threshold=${threshold%%%}
10761         echo -n "Check for uneven OSTs: "
10762         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10763
10764         if [[ $DIFF2 -gt $threshold ]]; then
10765                 echo "ok"
10766                 echo "Don't need to fill OST$MINI"
10767         else
10768                 # generate uneven OSTs. Write 2% over the QOS threshold value
10769                 echo "no"
10770                 DIFF=$((threshold - DIFF2 + 2))
10771                 DIFF2=$((MINV * DIFF / 100))
10772                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10773                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10774                         error "setstripe failed"
10775                 DIFF=$((DIFF2 / 2048))
10776                 i=0
10777                 while [ $i -lt $DIFF ]; do
10778                         i=$((i + 1))
10779                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10780                                 bs=2M count=1 2>/dev/null
10781                         echo -n .
10782                 done
10783                 echo .
10784                 sync
10785                 sleep_maxage
10786                 free_min_max
10787         fi
10788
10789         DIFF=$((MAXV - MINV))
10790         DIFF2=$((DIFF * 100 / MINV))
10791         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10792         if [ $DIFF2 -gt $threshold ]; then
10793                 echo "ok"
10794         else
10795                 echo "failed - QOS mode won't be used"
10796                 simple_cleanup_common
10797                 skip "QOS imbalance criteria not met"
10798         fi
10799
10800         MINI1=$MINI
10801         MINV1=$MINV
10802         MAXI1=$MAXI
10803         MAXV1=$MAXV
10804
10805         # now fill using QOS
10806         $LFS setstripe -c 1 $DIR/$tdir
10807         FILL=$((FILL / 200))
10808         if [ $FILL -gt 600 ]; then
10809                 FILL=600
10810         fi
10811         echo "writing $FILL files to QOS-assigned OSTs"
10812         i=0
10813         while [ $i -lt $FILL ]; do
10814                 i=$((i + 1))
10815                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10816                         count=1 2>/dev/null
10817                 echo -n .
10818         done
10819         echo "wrote $i 200k files"
10820         sync
10821         sleep_maxage
10822
10823         echo "Note: free space may not be updated, so measurements might be off"
10824         free_min_max
10825         DIFF2=$((MAXV - MINV))
10826         echo "free space delta: orig $DIFF final $DIFF2"
10827         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10828         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10829         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10830         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10831         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10832         if [[ $DIFF -gt 0 ]]; then
10833                 FILL=$((DIFF2 * 100 / DIFF - 100))
10834                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10835         fi
10836
10837         # Figure out which files were written where
10838         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10839                awk '/'$MINI1': / {print $2; exit}')
10840         echo $UUID
10841         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10842         echo "$MINC files created on smaller OST $MINI1"
10843         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10844                awk '/'$MAXI1': / {print $2; exit}')
10845         echo $UUID
10846         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10847         echo "$MAXC files created on larger OST $MAXI1"
10848         if [[ $MINC -gt 0 ]]; then
10849                 FILL=$((MAXC * 100 / MINC - 100))
10850                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10851         fi
10852         [[ $MAXC -gt $MINC ]] ||
10853                 error_ignore LU-9 "stripe QOS didn't balance free space"
10854         simple_cleanup_common
10855 }
10856 run_test 116a "stripe QOS: free space balance ==================="
10857
10858 test_116b() { # LU-2093
10859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10860         remote_mds_nodsh && skip "remote MDS with nodsh"
10861
10862 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10863         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10864                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10865         [ -z "$old_rr" ] && skip "no QOS"
10866         do_facet $SINGLEMDS lctl set_param \
10867                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10868         mkdir -p $DIR/$tdir
10869         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10870         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10871         do_facet $SINGLEMDS lctl set_param fail_loc=0
10872         rm -rf $DIR/$tdir
10873         do_facet $SINGLEMDS lctl set_param \
10874                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10875 }
10876 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10877
10878 test_117() # bug 10891
10879 {
10880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10881
10882         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10883         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10884         lctl set_param fail_loc=0x21e
10885         > $DIR/$tfile || error "truncate failed"
10886         lctl set_param fail_loc=0
10887         echo "Truncate succeeded."
10888         rm -f $DIR/$tfile
10889 }
10890 run_test 117 "verify osd extend =========="
10891
10892 NO_SLOW_RESENDCOUNT=4
10893 export OLD_RESENDCOUNT=""
10894 set_resend_count () {
10895         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10896         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10897         lctl set_param -n $PROC_RESENDCOUNT $1
10898         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10899 }
10900
10901 # for reduce test_118* time (b=14842)
10902 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10903
10904 # Reset async IO behavior after error case
10905 reset_async() {
10906         FILE=$DIR/reset_async
10907
10908         # Ensure all OSCs are cleared
10909         $LFS setstripe -c -1 $FILE
10910         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10911         sync
10912         rm $FILE
10913 }
10914
10915 test_118a() #bug 11710
10916 {
10917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10918
10919         reset_async
10920
10921         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10922         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10923         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10924
10925         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10926                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10927                 return 1;
10928         fi
10929         rm -f $DIR/$tfile
10930 }
10931 run_test 118a "verify O_SYNC works =========="
10932
10933 test_118b()
10934 {
10935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10936         remote_ost_nodsh && skip "remote OST with nodsh"
10937
10938         reset_async
10939
10940         #define OBD_FAIL_SRV_ENOENT 0x217
10941         set_nodes_failloc "$(osts_nodes)" 0x217
10942         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10943         RC=$?
10944         set_nodes_failloc "$(osts_nodes)" 0
10945         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10946         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10947                     grep -c writeback)
10948
10949         if [[ $RC -eq 0 ]]; then
10950                 error "Must return error due to dropped pages, rc=$RC"
10951                 return 1;
10952         fi
10953
10954         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10955                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10956                 return 1;
10957         fi
10958
10959         echo "Dirty pages not leaked on ENOENT"
10960
10961         # Due to the above error the OSC will issue all RPCs syncronously
10962         # until a subsequent RPC completes successfully without error.
10963         $MULTIOP $DIR/$tfile Ow4096yc
10964         rm -f $DIR/$tfile
10965
10966         return 0
10967 }
10968 run_test 118b "Reclaim dirty pages on fatal error =========="
10969
10970 test_118c()
10971 {
10972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10973
10974         # for 118c, restore the original resend count, LU-1940
10975         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10976                                 set_resend_count $OLD_RESENDCOUNT
10977         remote_ost_nodsh && skip "remote OST with nodsh"
10978
10979         reset_async
10980
10981         #define OBD_FAIL_OST_EROFS               0x216
10982         set_nodes_failloc "$(osts_nodes)" 0x216
10983
10984         # multiop should block due to fsync until pages are written
10985         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10986         MULTIPID=$!
10987         sleep 1
10988
10989         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10990                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10991         fi
10992
10993         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10994                     grep -c writeback)
10995         if [[ $WRITEBACK -eq 0 ]]; then
10996                 error "No page in writeback, writeback=$WRITEBACK"
10997         fi
10998
10999         set_nodes_failloc "$(osts_nodes)" 0
11000         wait $MULTIPID
11001         RC=$?
11002         if [[ $RC -ne 0 ]]; then
11003                 error "Multiop fsync failed, rc=$RC"
11004         fi
11005
11006         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11007         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11008                     grep -c writeback)
11009         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11010                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11011         fi
11012
11013         rm -f $DIR/$tfile
11014         echo "Dirty pages flushed via fsync on EROFS"
11015         return 0
11016 }
11017 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11018
11019 # continue to use small resend count to reduce test_118* time (b=14842)
11020 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11021
11022 test_118d()
11023 {
11024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11025         remote_ost_nodsh && skip "remote OST with nodsh"
11026
11027         reset_async
11028
11029         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11030         set_nodes_failloc "$(osts_nodes)" 0x214
11031         # multiop should block due to fsync until pages are written
11032         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11033         MULTIPID=$!
11034         sleep 1
11035
11036         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11037                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11038         fi
11039
11040         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11041                     grep -c writeback)
11042         if [[ $WRITEBACK -eq 0 ]]; then
11043                 error "No page in writeback, writeback=$WRITEBACK"
11044         fi
11045
11046         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11047         set_nodes_failloc "$(osts_nodes)" 0
11048
11049         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11050         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11051                     grep -c writeback)
11052         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11053                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11054         fi
11055
11056         rm -f $DIR/$tfile
11057         echo "Dirty pages gaurenteed flushed via fsync"
11058         return 0
11059 }
11060 run_test 118d "Fsync validation inject a delay of the bulk =========="
11061
11062 test_118f() {
11063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11064
11065         reset_async
11066
11067         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11068         lctl set_param fail_loc=0x8000040a
11069
11070         # Should simulate EINVAL error which is fatal
11071         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11072         RC=$?
11073         if [[ $RC -eq 0 ]]; then
11074                 error "Must return error due to dropped pages, rc=$RC"
11075         fi
11076
11077         lctl set_param fail_loc=0x0
11078
11079         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11080         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11081         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11082                     grep -c writeback)
11083         if [[ $LOCKED -ne 0 ]]; then
11084                 error "Locked pages remain in cache, locked=$LOCKED"
11085         fi
11086
11087         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11088                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11089         fi
11090
11091         rm -f $DIR/$tfile
11092         echo "No pages locked after fsync"
11093
11094         reset_async
11095         return 0
11096 }
11097 run_test 118f "Simulate unrecoverable OSC side error =========="
11098
11099 test_118g() {
11100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11101
11102         reset_async
11103
11104         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11105         lctl set_param fail_loc=0x406
11106
11107         # simulate local -ENOMEM
11108         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11109         RC=$?
11110
11111         lctl set_param fail_loc=0
11112         if [[ $RC -eq 0 ]]; then
11113                 error "Must return error due to dropped pages, rc=$RC"
11114         fi
11115
11116         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11117         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11118         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11119                         grep -c writeback)
11120         if [[ $LOCKED -ne 0 ]]; then
11121                 error "Locked pages remain in cache, locked=$LOCKED"
11122         fi
11123
11124         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11125                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11126         fi
11127
11128         rm -f $DIR/$tfile
11129         echo "No pages locked after fsync"
11130
11131         reset_async
11132         return 0
11133 }
11134 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11135
11136 test_118h() {
11137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11138         remote_ost_nodsh && skip "remote OST with nodsh"
11139
11140         reset_async
11141
11142         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11143         set_nodes_failloc "$(osts_nodes)" 0x20e
11144         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11145         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11146         RC=$?
11147
11148         set_nodes_failloc "$(osts_nodes)" 0
11149         if [[ $RC -eq 0 ]]; then
11150                 error "Must return error due to dropped pages, rc=$RC"
11151         fi
11152
11153         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11154         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11155         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11156                     grep -c writeback)
11157         if [[ $LOCKED -ne 0 ]]; then
11158                 error "Locked pages remain in cache, locked=$LOCKED"
11159         fi
11160
11161         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11162                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11163         fi
11164
11165         rm -f $DIR/$tfile
11166         echo "No pages locked after fsync"
11167
11168         return 0
11169 }
11170 run_test 118h "Verify timeout in handling recoverables errors  =========="
11171
11172 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11173
11174 test_118i() {
11175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11176         remote_ost_nodsh && skip "remote OST with nodsh"
11177
11178         reset_async
11179
11180         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11181         set_nodes_failloc "$(osts_nodes)" 0x20e
11182
11183         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11184         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11185         PID=$!
11186         sleep 5
11187         set_nodes_failloc "$(osts_nodes)" 0
11188
11189         wait $PID
11190         RC=$?
11191         if [[ $RC -ne 0 ]]; then
11192                 error "got error, but should be not, rc=$RC"
11193         fi
11194
11195         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11196         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11197         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11198         if [[ $LOCKED -ne 0 ]]; then
11199                 error "Locked pages remain in cache, locked=$LOCKED"
11200         fi
11201
11202         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11203                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11204         fi
11205
11206         rm -f $DIR/$tfile
11207         echo "No pages locked after fsync"
11208
11209         return 0
11210 }
11211 run_test 118i "Fix error before timeout in recoverable error  =========="
11212
11213 [ "$SLOW" = "no" ] && set_resend_count 4
11214
11215 test_118j() {
11216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11217         remote_ost_nodsh && skip "remote OST with nodsh"
11218
11219         reset_async
11220
11221         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11222         set_nodes_failloc "$(osts_nodes)" 0x220
11223
11224         # return -EIO from OST
11225         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11226         RC=$?
11227         set_nodes_failloc "$(osts_nodes)" 0x0
11228         if [[ $RC -eq 0 ]]; then
11229                 error "Must return error due to dropped pages, rc=$RC"
11230         fi
11231
11232         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11233         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11234         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11235         if [[ $LOCKED -ne 0 ]]; then
11236                 error "Locked pages remain in cache, locked=$LOCKED"
11237         fi
11238
11239         # in recoverable error on OST we want resend and stay until it finished
11240         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11241                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11242         fi
11243
11244         rm -f $DIR/$tfile
11245         echo "No pages locked after fsync"
11246
11247         return 0
11248 }
11249 run_test 118j "Simulate unrecoverable OST side error =========="
11250
11251 test_118k()
11252 {
11253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11254         remote_ost_nodsh && skip "remote OSTs with nodsh"
11255
11256         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11257         set_nodes_failloc "$(osts_nodes)" 0x20e
11258         test_mkdir $DIR/$tdir
11259
11260         for ((i=0;i<10;i++)); do
11261                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11262                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11263                 SLEEPPID=$!
11264                 sleep 0.500s
11265                 kill $SLEEPPID
11266                 wait $SLEEPPID
11267         done
11268
11269         set_nodes_failloc "$(osts_nodes)" 0
11270         rm -rf $DIR/$tdir
11271 }
11272 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11273
11274 test_118l() # LU-646
11275 {
11276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11277
11278         test_mkdir $DIR/$tdir
11279         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11280         rm -rf $DIR/$tdir
11281 }
11282 run_test 118l "fsync dir"
11283
11284 test_118m() # LU-3066
11285 {
11286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11287
11288         test_mkdir $DIR/$tdir
11289         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11290         rm -rf $DIR/$tdir
11291 }
11292 run_test 118m "fdatasync dir ========="
11293
11294 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11295
11296 test_118n()
11297 {
11298         local begin
11299         local end
11300
11301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11302         remote_ost_nodsh && skip "remote OSTs with nodsh"
11303
11304         # Sleep to avoid a cached response.
11305         #define OBD_STATFS_CACHE_SECONDS 1
11306         sleep 2
11307
11308         # Inject a 10 second delay in the OST_STATFS handler.
11309         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11310         set_nodes_failloc "$(osts_nodes)" 0x242
11311
11312         begin=$SECONDS
11313         stat --file-system $MOUNT > /dev/null
11314         end=$SECONDS
11315
11316         set_nodes_failloc "$(osts_nodes)" 0
11317
11318         if ((end - begin > 20)); then
11319             error "statfs took $((end - begin)) seconds, expected 10"
11320         fi
11321 }
11322 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11323
11324 test_119a() # bug 11737
11325 {
11326         BSIZE=$((512 * 1024))
11327         directio write $DIR/$tfile 0 1 $BSIZE
11328         # We ask to read two blocks, which is more than a file size.
11329         # directio will indicate an error when requested and actual
11330         # sizes aren't equeal (a normal situation in this case) and
11331         # print actual read amount.
11332         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11333         if [ "$NOB" != "$BSIZE" ]; then
11334                 error "read $NOB bytes instead of $BSIZE"
11335         fi
11336         rm -f $DIR/$tfile
11337 }
11338 run_test 119a "Short directIO read must return actual read amount"
11339
11340 test_119b() # bug 11737
11341 {
11342         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11343
11344         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11345         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11346         sync
11347         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11348                 error "direct read failed"
11349         rm -f $DIR/$tfile
11350 }
11351 run_test 119b "Sparse directIO read must return actual read amount"
11352
11353 test_119c() # bug 13099
11354 {
11355         BSIZE=1048576
11356         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11357         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11358         rm -f $DIR/$tfile
11359 }
11360 run_test 119c "Testing for direct read hitting hole"
11361
11362 test_119d() # bug 15950
11363 {
11364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11365
11366         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11367         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11368         BSIZE=1048576
11369         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11370         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11371         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11372         lctl set_param fail_loc=0x40d
11373         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11374         pid_dio=$!
11375         sleep 1
11376         cat $DIR/$tfile > /dev/null &
11377         lctl set_param fail_loc=0
11378         pid_reads=$!
11379         wait $pid_dio
11380         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11381         sleep 2
11382         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11383         error "the read rpcs have not completed in 2s"
11384         rm -f $DIR/$tfile
11385         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11386 }
11387 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11388
11389 test_120a() {
11390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11391         remote_mds_nodsh && skip "remote MDS with nodsh"
11392         test_mkdir -i0 -c1 $DIR/$tdir
11393         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11394                 skip_env "no early lock cancel on server"
11395
11396         lru_resize_disable mdc
11397         lru_resize_disable osc
11398         cancel_lru_locks mdc
11399         # asynchronous object destroy at MDT could cause bl ast to client
11400         cancel_lru_locks osc
11401
11402         stat $DIR/$tdir > /dev/null
11403         can1=$(do_facet mds1 \
11404                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11405                awk '/ldlm_cancel/ {print $2}')
11406         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11407                awk '/ldlm_bl_callback/ {print $2}')
11408         test_mkdir -i0 -c1 $DIR/$tdir/d1
11409         can2=$(do_facet mds1 \
11410                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11411                awk '/ldlm_cancel/ {print $2}')
11412         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11413                awk '/ldlm_bl_callback/ {print $2}')
11414         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11415         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11416         lru_resize_enable mdc
11417         lru_resize_enable osc
11418 }
11419 run_test 120a "Early Lock Cancel: mkdir test"
11420
11421 test_120b() {
11422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11423         remote_mds_nodsh && skip "remote MDS with nodsh"
11424         test_mkdir $DIR/$tdir
11425         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11426                 skip_env "no early lock cancel on server"
11427
11428         lru_resize_disable mdc
11429         lru_resize_disable osc
11430         cancel_lru_locks mdc
11431         stat $DIR/$tdir > /dev/null
11432         can1=$(do_facet $SINGLEMDS \
11433                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11434                awk '/ldlm_cancel/ {print $2}')
11435         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11436                awk '/ldlm_bl_callback/ {print $2}')
11437         touch $DIR/$tdir/f1
11438         can2=$(do_facet $SINGLEMDS \
11439                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11440                awk '/ldlm_cancel/ {print $2}')
11441         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11442                awk '/ldlm_bl_callback/ {print $2}')
11443         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11444         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11445         lru_resize_enable mdc
11446         lru_resize_enable osc
11447 }
11448 run_test 120b "Early Lock Cancel: create test"
11449
11450 test_120c() {
11451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11452         remote_mds_nodsh && skip "remote MDS with nodsh"
11453         test_mkdir -i0 -c1 $DIR/$tdir
11454         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11455                 skip "no early lock cancel on server"
11456
11457         lru_resize_disable mdc
11458         lru_resize_disable osc
11459         test_mkdir -i0 -c1 $DIR/$tdir/d1
11460         test_mkdir -i0 -c1 $DIR/$tdir/d2
11461         touch $DIR/$tdir/d1/f1
11462         cancel_lru_locks mdc
11463         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11464         can1=$(do_facet mds1 \
11465                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11466                awk '/ldlm_cancel/ {print $2}')
11467         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11468                awk '/ldlm_bl_callback/ {print $2}')
11469         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11470         can2=$(do_facet mds1 \
11471                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11472                awk '/ldlm_cancel/ {print $2}')
11473         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11474                awk '/ldlm_bl_callback/ {print $2}')
11475         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11476         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11477         lru_resize_enable mdc
11478         lru_resize_enable osc
11479 }
11480 run_test 120c "Early Lock Cancel: link test"
11481
11482 test_120d() {
11483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11484         remote_mds_nodsh && skip "remote MDS with nodsh"
11485         test_mkdir -i0 -c1 $DIR/$tdir
11486         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11487                 skip_env "no early lock cancel on server"
11488
11489         lru_resize_disable mdc
11490         lru_resize_disable osc
11491         touch $DIR/$tdir
11492         cancel_lru_locks mdc
11493         stat $DIR/$tdir > /dev/null
11494         can1=$(do_facet mds1 \
11495                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11496                awk '/ldlm_cancel/ {print $2}')
11497         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11498                awk '/ldlm_bl_callback/ {print $2}')
11499         chmod a+x $DIR/$tdir
11500         can2=$(do_facet mds1 \
11501                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11502                awk '/ldlm_cancel/ {print $2}')
11503         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11504                awk '/ldlm_bl_callback/ {print $2}')
11505         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11506         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11507         lru_resize_enable mdc
11508         lru_resize_enable osc
11509 }
11510 run_test 120d "Early Lock Cancel: setattr test"
11511
11512 test_120e() {
11513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11514         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11515                 skip_env "no early lock cancel on server"
11516         remote_mds_nodsh && skip "remote MDS with nodsh"
11517
11518         local dlmtrace_set=false
11519
11520         test_mkdir -i0 -c1 $DIR/$tdir
11521         lru_resize_disable mdc
11522         lru_resize_disable osc
11523         ! $LCTL get_param debug | grep -q dlmtrace &&
11524                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11525         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11526         cancel_lru_locks mdc
11527         cancel_lru_locks osc
11528         dd if=$DIR/$tdir/f1 of=/dev/null
11529         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11530         # XXX client can not do early lock cancel of OST lock
11531         # during unlink (LU-4206), so cancel osc lock now.
11532         sleep 2
11533         cancel_lru_locks osc
11534         can1=$(do_facet mds1 \
11535                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11536                awk '/ldlm_cancel/ {print $2}')
11537         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11538                awk '/ldlm_bl_callback/ {print $2}')
11539         unlink $DIR/$tdir/f1
11540         sleep 5
11541         can2=$(do_facet mds1 \
11542                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11543                awk '/ldlm_cancel/ {print $2}')
11544         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11545                awk '/ldlm_bl_callback/ {print $2}')
11546         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11547                 $LCTL dk $TMP/cancel.debug.txt
11548         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11549                 $LCTL dk $TMP/blocking.debug.txt
11550         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11551         lru_resize_enable mdc
11552         lru_resize_enable osc
11553 }
11554 run_test 120e "Early Lock Cancel: unlink test"
11555
11556 test_120f() {
11557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11558         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11559                 skip_env "no early lock cancel on server"
11560         remote_mds_nodsh && skip "remote MDS with nodsh"
11561
11562         test_mkdir -i0 -c1 $DIR/$tdir
11563         lru_resize_disable mdc
11564         lru_resize_disable osc
11565         test_mkdir -i0 -c1 $DIR/$tdir/d1
11566         test_mkdir -i0 -c1 $DIR/$tdir/d2
11567         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11568         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11569         cancel_lru_locks mdc
11570         cancel_lru_locks osc
11571         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11572         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11573         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11574         # XXX client can not do early lock cancel of OST lock
11575         # during rename (LU-4206), so cancel osc lock now.
11576         sleep 2
11577         cancel_lru_locks osc
11578         can1=$(do_facet mds1 \
11579                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11580                awk '/ldlm_cancel/ {print $2}')
11581         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11582                awk '/ldlm_bl_callback/ {print $2}')
11583         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11584         sleep 5
11585         can2=$(do_facet mds1 \
11586                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11587                awk '/ldlm_cancel/ {print $2}')
11588         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11589                awk '/ldlm_bl_callback/ {print $2}')
11590         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11591         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11592         lru_resize_enable mdc
11593         lru_resize_enable osc
11594 }
11595 run_test 120f "Early Lock Cancel: rename test"
11596
11597 test_120g() {
11598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11599         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11600                 skip_env "no early lock cancel on server"
11601         remote_mds_nodsh && skip "remote MDS with nodsh"
11602
11603         lru_resize_disable mdc
11604         lru_resize_disable osc
11605         count=10000
11606         echo create $count files
11607         test_mkdir $DIR/$tdir
11608         cancel_lru_locks mdc
11609         cancel_lru_locks osc
11610         t0=$(date +%s)
11611
11612         can0=$(do_facet $SINGLEMDS \
11613                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11614                awk '/ldlm_cancel/ {print $2}')
11615         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11616                awk '/ldlm_bl_callback/ {print $2}')
11617         createmany -o $DIR/$tdir/f $count
11618         sync
11619         can1=$(do_facet $SINGLEMDS \
11620                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11621                awk '/ldlm_cancel/ {print $2}')
11622         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11623                awk '/ldlm_bl_callback/ {print $2}')
11624         t1=$(date +%s)
11625         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11626         echo rm $count files
11627         rm -r $DIR/$tdir
11628         sync
11629         can2=$(do_facet $SINGLEMDS \
11630                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11631                awk '/ldlm_cancel/ {print $2}')
11632         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11633                awk '/ldlm_bl_callback/ {print $2}')
11634         t2=$(date +%s)
11635         echo total: $count removes in $((t2-t1))
11636         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11637         sleep 2
11638         # wait for commitment of removal
11639         lru_resize_enable mdc
11640         lru_resize_enable osc
11641 }
11642 run_test 120g "Early Lock Cancel: performance test"
11643
11644 test_121() { #bug #10589
11645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11646
11647         rm -rf $DIR/$tfile
11648         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11649 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11650         lctl set_param fail_loc=0x310
11651         cancel_lru_locks osc > /dev/null
11652         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11653         lctl set_param fail_loc=0
11654         [[ $reads -eq $writes ]] ||
11655                 error "read $reads blocks, must be $writes blocks"
11656 }
11657 run_test 121 "read cancel race ========="
11658
11659 test_123a_base() { # was test 123, statahead(bug 11401)
11660         local lsx="$1"
11661
11662         SLOWOK=0
11663         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11664                 log "testing UP system. Performance may be lower than expected."
11665                 SLOWOK=1
11666         fi
11667
11668         rm -rf $DIR/$tdir
11669         test_mkdir $DIR/$tdir
11670         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11671         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11672         MULT=10
11673         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11674                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11675
11676                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11677                 lctl set_param -n llite.*.statahead_max 0
11678                 lctl get_param llite.*.statahead_max
11679                 cancel_lru_locks mdc
11680                 cancel_lru_locks osc
11681                 stime=$(date +%s)
11682                 time $lsx $DIR/$tdir | wc -l
11683                 etime=$(date +%s)
11684                 delta=$((etime - stime))
11685                 log "$lsx $i files without statahead: $delta sec"
11686                 lctl set_param llite.*.statahead_max=$max
11687
11688                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11689                         grep "statahead wrong:" | awk '{print $3}')
11690                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11691                 cancel_lru_locks mdc
11692                 cancel_lru_locks osc
11693                 stime=$(date +%s)
11694                 time $lsx $DIR/$tdir | wc -l
11695                 etime=$(date +%s)
11696                 delta_sa=$((etime - stime))
11697                 log "$lsx $i files with statahead: $delta_sa sec"
11698                 lctl get_param -n llite.*.statahead_stats
11699                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11700                         grep "statahead wrong:" | awk '{print $3}')
11701
11702                 [[ $swrong -lt $ewrong ]] &&
11703                         log "statahead was stopped, maybe too many locks held!"
11704                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11705
11706                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11707                         max=$(lctl get_param -n llite.*.statahead_max |
11708                                 head -n 1)
11709                         lctl set_param -n llite.*.statahead_max 0
11710                         lctl get_param llite.*.statahead_max
11711                         cancel_lru_locks mdc
11712                         cancel_lru_locks osc
11713                         stime=$(date +%s)
11714                         time $lsx $DIR/$tdir | wc -l
11715                         etime=$(date +%s)
11716                         delta=$((etime - stime))
11717                         log "$lsx $i files again without statahead: $delta sec"
11718                         lctl set_param llite.*.statahead_max=$max
11719                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11720                                 if [  $SLOWOK -eq 0 ]; then
11721                                         error "$lsx $i files is slower with statahead!"
11722                                 else
11723                                         log "$lsx $i files is slower with statahead!"
11724                                 fi
11725                                 break
11726                         fi
11727                 fi
11728
11729                 [ $delta -gt 20 ] && break
11730                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11731                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11732         done
11733         log "$lsx done"
11734
11735         stime=$(date +%s)
11736         rm -r $DIR/$tdir
11737         sync
11738         etime=$(date +%s)
11739         delta=$((etime - stime))
11740         log "rm -r $DIR/$tdir/: $delta seconds"
11741         log "rm done"
11742         lctl get_param -n llite.*.statahead_stats
11743 }
11744
11745 test_123aa() {
11746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11747
11748         test_123a_base "ls -l"
11749 }
11750 run_test 123aa "verify statahead work"
11751
11752 test_123ab() {
11753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11754
11755         statx_supported || skip_env "Test must be statx() syscall supported"
11756
11757         test_123a_base "$STATX -l"
11758 }
11759 run_test 123ab "verify statahead work by using statx"
11760
11761 test_123ac() {
11762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11763
11764         statx_supported || skip_env "Test must be statx() syscall supported"
11765
11766         local rpcs_before
11767         local rpcs_after
11768         local agl_before
11769         local agl_after
11770
11771         cancel_lru_locks $OSC
11772         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11773         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11774                 awk '/agl.total:/ {print $3}')
11775         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11776         test_123a_base "$STATX --cached=always -D"
11777         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11778                 awk '/agl.total:/ {print $3}')
11779         [ $agl_before -eq $agl_after ] ||
11780                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11781         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11782         [ $rpcs_after -eq $rpcs_before ] ||
11783                 error "$STATX should not send glimpse RPCs to $OSC"
11784 }
11785 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11786
11787 test_123b () { # statahead(bug 15027)
11788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11789
11790         test_mkdir $DIR/$tdir
11791         createmany -o $DIR/$tdir/$tfile-%d 1000
11792
11793         cancel_lru_locks mdc
11794         cancel_lru_locks osc
11795
11796 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11797         lctl set_param fail_loc=0x80000803
11798         ls -lR $DIR/$tdir > /dev/null
11799         log "ls done"
11800         lctl set_param fail_loc=0x0
11801         lctl get_param -n llite.*.statahead_stats
11802         rm -r $DIR/$tdir
11803         sync
11804
11805 }
11806 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11807
11808 test_123c() {
11809         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11810
11811         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11812         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11813         touch $DIR/$tdir.1/{1..3}
11814         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11815
11816         remount_client $MOUNT
11817
11818         $MULTIOP $DIR/$tdir.0 Q
11819
11820         # let statahead to complete
11821         ls -l $DIR/$tdir.0 > /dev/null
11822
11823         testid=$(echo $TESTNAME | tr '_' ' ')
11824         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11825                 error "statahead warning" || true
11826 }
11827 run_test 123c "Can not initialize inode warning on DNE statahead"
11828
11829 test_124a() {
11830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11831         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11832                 skip_env "no lru resize on server"
11833
11834         local NR=2000
11835
11836         test_mkdir $DIR/$tdir
11837
11838         log "create $NR files at $DIR/$tdir"
11839         createmany -o $DIR/$tdir/f $NR ||
11840                 error "failed to create $NR files in $DIR/$tdir"
11841
11842         cancel_lru_locks mdc
11843         ls -l $DIR/$tdir > /dev/null
11844
11845         local NSDIR=""
11846         local LRU_SIZE=0
11847         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11848                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11849                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11850                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11851                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11852                         log "NSDIR=$NSDIR"
11853                         log "NS=$(basename $NSDIR)"
11854                         break
11855                 fi
11856         done
11857
11858         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11859                 skip "Not enough cached locks created!"
11860         fi
11861         log "LRU=$LRU_SIZE"
11862
11863         local SLEEP=30
11864
11865         # We know that lru resize allows one client to hold $LIMIT locks
11866         # for 10h. After that locks begin to be killed by client.
11867         local MAX_HRS=10
11868         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11869         log "LIMIT=$LIMIT"
11870         if [ $LIMIT -lt $LRU_SIZE ]; then
11871                 skip "Limit is too small $LIMIT"
11872         fi
11873
11874         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11875         # killing locks. Some time was spent for creating locks. This means
11876         # that up to the moment of sleep finish we must have killed some of
11877         # them (10-100 locks). This depends on how fast ther were created.
11878         # Many of them were touched in almost the same moment and thus will
11879         # be killed in groups.
11880         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11881
11882         # Use $LRU_SIZE_B here to take into account real number of locks
11883         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11884         local LRU_SIZE_B=$LRU_SIZE
11885         log "LVF=$LVF"
11886         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11887         log "OLD_LVF=$OLD_LVF"
11888         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11889
11890         # Let's make sure that we really have some margin. Client checks
11891         # cached locks every 10 sec.
11892         SLEEP=$((SLEEP+20))
11893         log "Sleep ${SLEEP} sec"
11894         local SEC=0
11895         while ((SEC<$SLEEP)); do
11896                 echo -n "..."
11897                 sleep 5
11898                 SEC=$((SEC+5))
11899                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11900                 echo -n "$LRU_SIZE"
11901         done
11902         echo ""
11903         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11904         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11905
11906         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11907                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11908                 unlinkmany $DIR/$tdir/f $NR
11909                 return
11910         }
11911
11912         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11913         log "unlink $NR files at $DIR/$tdir"
11914         unlinkmany $DIR/$tdir/f $NR
11915 }
11916 run_test 124a "lru resize ======================================="
11917
11918 get_max_pool_limit()
11919 {
11920         local limit=$($LCTL get_param \
11921                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11922         local max=0
11923         for l in $limit; do
11924                 if [[ $l -gt $max ]]; then
11925                         max=$l
11926                 fi
11927         done
11928         echo $max
11929 }
11930
11931 test_124b() {
11932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11933         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11934                 skip_env "no lru resize on server"
11935
11936         LIMIT=$(get_max_pool_limit)
11937
11938         NR=$(($(default_lru_size)*20))
11939         if [[ $NR -gt $LIMIT ]]; then
11940                 log "Limit lock number by $LIMIT locks"
11941                 NR=$LIMIT
11942         fi
11943
11944         IFree=$(mdsrate_inodes_available)
11945         if [ $IFree -lt $NR ]; then
11946                 log "Limit lock number by $IFree inodes"
11947                 NR=$IFree
11948         fi
11949
11950         lru_resize_disable mdc
11951         test_mkdir -p $DIR/$tdir/disable_lru_resize
11952
11953         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11954         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11955         cancel_lru_locks mdc
11956         stime=`date +%s`
11957         PID=""
11958         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11959         PID="$PID $!"
11960         sleep 2
11961         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11962         PID="$PID $!"
11963         sleep 2
11964         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11965         PID="$PID $!"
11966         wait $PID
11967         etime=`date +%s`
11968         nolruresize_delta=$((etime-stime))
11969         log "ls -la time: $nolruresize_delta seconds"
11970         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11971         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11972
11973         lru_resize_enable mdc
11974         test_mkdir -p $DIR/$tdir/enable_lru_resize
11975
11976         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11977         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11978         cancel_lru_locks mdc
11979         stime=`date +%s`
11980         PID=""
11981         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11982         PID="$PID $!"
11983         sleep 2
11984         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11985         PID="$PID $!"
11986         sleep 2
11987         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11988         PID="$PID $!"
11989         wait $PID
11990         etime=`date +%s`
11991         lruresize_delta=$((etime-stime))
11992         log "ls -la time: $lruresize_delta seconds"
11993         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11994
11995         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11996                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11997         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11998                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11999         else
12000                 log "lru resize performs the same with no lru resize"
12001         fi
12002         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12003 }
12004 run_test 124b "lru resize (performance test) ======================="
12005
12006 test_124c() {
12007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12008         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12009                 skip_env "no lru resize on server"
12010
12011         # cache ununsed locks on client
12012         local nr=100
12013         cancel_lru_locks mdc
12014         test_mkdir $DIR/$tdir
12015         createmany -o $DIR/$tdir/f $nr ||
12016                 error "failed to create $nr files in $DIR/$tdir"
12017         ls -l $DIR/$tdir > /dev/null
12018
12019         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12020         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12021         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12022         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12023         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12024
12025         # set lru_max_age to 1 sec
12026         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12027         echo "sleep $((recalc_p * 2)) seconds..."
12028         sleep $((recalc_p * 2))
12029
12030         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12031         # restore lru_max_age
12032         $LCTL set_param -n $nsdir.lru_max_age $max_age
12033         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12034         unlinkmany $DIR/$tdir/f $nr
12035 }
12036 run_test 124c "LRUR cancel very aged locks"
12037
12038 test_124d() {
12039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12040         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12041                 skip_env "no lru resize on server"
12042
12043         # cache ununsed locks on client
12044         local nr=100
12045
12046         lru_resize_disable mdc
12047         stack_trap "lru_resize_enable mdc" EXIT
12048
12049         cancel_lru_locks mdc
12050
12051         # asynchronous object destroy at MDT could cause bl ast to client
12052         test_mkdir $DIR/$tdir
12053         createmany -o $DIR/$tdir/f $nr ||
12054                 error "failed to create $nr files in $DIR/$tdir"
12055         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12056
12057         ls -l $DIR/$tdir > /dev/null
12058
12059         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12060         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12061         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12062         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12063
12064         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12065
12066         # set lru_max_age to 1 sec
12067         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12068         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12069
12070         echo "sleep $((recalc_p * 2)) seconds..."
12071         sleep $((recalc_p * 2))
12072
12073         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12074
12075         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12076 }
12077 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12078
12079 test_125() { # 13358
12080         $LCTL get_param -n llite.*.client_type | grep -q local ||
12081                 skip "must run as local client"
12082         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12083                 skip_env "must have acl enabled"
12084         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12085
12086         test_mkdir $DIR/$tdir
12087         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12088         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12089         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12090 }
12091 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12092
12093 test_126() { # bug 12829/13455
12094         $GSS && skip_env "must run as gss disabled"
12095         $LCTL get_param -n llite.*.client_type | grep -q local ||
12096                 skip "must run as local client"
12097         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12098
12099         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12100         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12101         rm -f $DIR/$tfile
12102         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12103 }
12104 run_test 126 "check that the fsgid provided by the client is taken into account"
12105
12106 test_127a() { # bug 15521
12107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12108         local name count samp unit min max sum sumsq
12109
12110         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12111         echo "stats before reset"
12112         $LCTL get_param osc.*.stats
12113         $LCTL set_param osc.*.stats=0
12114         local fsize=$((2048 * 1024))
12115
12116         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12117         cancel_lru_locks osc
12118         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12119
12120         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12121         stack_trap "rm -f $TMP/$tfile.tmp"
12122         while read name count samp unit min max sum sumsq; do
12123                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12124                 [ ! $min ] && error "Missing min value for $name proc entry"
12125                 eval $name=$count || error "Wrong proc format"
12126
12127                 case $name in
12128                 read_bytes|write_bytes)
12129                         [[ "$unit" =~ "bytes" ]] ||
12130                                 error "unit is not 'bytes': $unit"
12131                         (( $min >= 4096 )) || error "min is too small: $min"
12132                         (( $min <= $fsize )) || error "min is too big: $min"
12133                         (( $max >= 4096 )) || error "max is too small: $max"
12134                         (( $max <= $fsize )) || error "max is too big: $max"
12135                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12136                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12137                                 error "sumsquare is too small: $sumsq"
12138                         (( $sumsq <= $fsize * $fsize )) ||
12139                                 error "sumsquare is too big: $sumsq"
12140                         ;;
12141                 ost_read|ost_write)
12142                         [[ "$unit" =~ "usec" ]] ||
12143                                 error "unit is not 'usec': $unit"
12144                         ;;
12145                 *)      ;;
12146                 esac
12147         done < $DIR/$tfile.tmp
12148
12149         #check that we actually got some stats
12150         [ "$read_bytes" ] || error "Missing read_bytes stats"
12151         [ "$write_bytes" ] || error "Missing write_bytes stats"
12152         [ "$read_bytes" != 0 ] || error "no read done"
12153         [ "$write_bytes" != 0 ] || error "no write done"
12154 }
12155 run_test 127a "verify the client stats are sane"
12156
12157 test_127b() { # bug LU-333
12158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12159         local name count samp unit min max sum sumsq
12160
12161         echo "stats before reset"
12162         $LCTL get_param llite.*.stats
12163         $LCTL set_param llite.*.stats=0
12164
12165         # perform 2 reads and writes so MAX is different from SUM.
12166         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12167         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12168         cancel_lru_locks osc
12169         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12170         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12171
12172         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12173         stack_trap "rm -f $TMP/$tfile.tmp"
12174         while read name count samp unit min max sum sumsq; do
12175                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12176                 eval $name=$count || error "Wrong proc format"
12177
12178                 case $name in
12179                 read_bytes|write_bytes)
12180                         [[ "$unit" =~ "bytes" ]] ||
12181                                 error "unit is not 'bytes': $unit"
12182                         (( $count == 2 )) || error "count is not 2: $count"
12183                         (( $min == $PAGE_SIZE )) ||
12184                                 error "min is not $PAGE_SIZE: $min"
12185                         (( $max == $PAGE_SIZE )) ||
12186                                 error "max is not $PAGE_SIZE: $max"
12187                         (( $sum == $PAGE_SIZE * 2 )) ||
12188                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12189                         ;;
12190                 read|write)
12191                         [[ "$unit" =~ "usec" ]] ||
12192                                 error "unit is not 'usec': $unit"
12193                         ;;
12194                 *)      ;;
12195                 esac
12196         done < $TMP/$tfile.tmp
12197
12198         #check that we actually got some stats
12199         [ "$read_bytes" ] || error "Missing read_bytes stats"
12200         [ "$write_bytes" ] || error "Missing write_bytes stats"
12201         [ "$read_bytes" != 0 ] || error "no read done"
12202         [ "$write_bytes" != 0 ] || error "no write done"
12203 }
12204 run_test 127b "verify the llite client stats are sane"
12205
12206 test_127c() { # LU-12394
12207         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12208         local size
12209         local bsize
12210         local reads
12211         local writes
12212         local count
12213
12214         $LCTL set_param llite.*.extents_stats=1
12215         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12216
12217         # Use two stripes so there is enough space in default config
12218         $LFS setstripe -c 2 $DIR/$tfile
12219
12220         # Extent stats start at 0-4K and go in power of two buckets
12221         # LL_HIST_START = 12 --> 2^12 = 4K
12222         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12223         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12224         # small configs
12225         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12226                 do
12227                 # Write and read, 2x each, second time at a non-zero offset
12228                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12229                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12230                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12231                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12232                 rm -f $DIR/$tfile
12233         done
12234
12235         $LCTL get_param llite.*.extents_stats
12236
12237         count=2
12238         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12239                 do
12240                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12241                                 grep -m 1 $bsize)
12242                 reads=$(echo $bucket | awk '{print $5}')
12243                 writes=$(echo $bucket | awk '{print $9}')
12244                 [ "$reads" -eq $count ] ||
12245                         error "$reads reads in < $bsize bucket, expect $count"
12246                 [ "$writes" -eq $count ] ||
12247                         error "$writes writes in < $bsize bucket, expect $count"
12248         done
12249
12250         # Test mmap write and read
12251         $LCTL set_param llite.*.extents_stats=c
12252         size=512
12253         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12254         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12255         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12256
12257         $LCTL get_param llite.*.extents_stats
12258
12259         count=$(((size*1024) / PAGE_SIZE))
12260
12261         bsize=$((2 * PAGE_SIZE / 1024))K
12262
12263         bucket=$($LCTL get_param -n llite.*.extents_stats |
12264                         grep -m 1 $bsize)
12265         reads=$(echo $bucket | awk '{print $5}')
12266         writes=$(echo $bucket | awk '{print $9}')
12267         # mmap writes fault in the page first, creating an additonal read
12268         [ "$reads" -eq $((2 * count)) ] ||
12269                 error "$reads reads in < $bsize bucket, expect $count"
12270         [ "$writes" -eq $count ] ||
12271                 error "$writes writes in < $bsize bucket, expect $count"
12272 }
12273 run_test 127c "test llite extent stats with regular & mmap i/o"
12274
12275 test_128() { # bug 15212
12276         touch $DIR/$tfile
12277         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12278                 find $DIR/$tfile
12279                 find $DIR/$tfile
12280         EOF
12281
12282         result=$(grep error $TMP/$tfile.log)
12283         rm -f $DIR/$tfile $TMP/$tfile.log
12284         [ -z "$result" ] ||
12285                 error "consecutive find's under interactive lfs failed"
12286 }
12287 run_test 128 "interactive lfs for 2 consecutive find's"
12288
12289 set_dir_limits () {
12290         local mntdev
12291         local canondev
12292         local node
12293
12294         local ldproc=/proc/fs/ldiskfs
12295         local facets=$(get_facets MDS)
12296
12297         for facet in ${facets//,/ }; do
12298                 canondev=$(ldiskfs_canon \
12299                            *.$(convert_facet2label $facet).mntdev $facet)
12300                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12301                         ldproc=/sys/fs/ldiskfs
12302                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12303                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12304         done
12305 }
12306
12307 check_mds_dmesg() {
12308         local facets=$(get_facets MDS)
12309         for facet in ${facets//,/ }; do
12310                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12311         done
12312         return 1
12313 }
12314
12315 test_129() {
12316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12317         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12318                 skip "Need MDS version with at least 2.5.56"
12319         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12320                 skip_env "ldiskfs only test"
12321         fi
12322         remote_mds_nodsh && skip "remote MDS with nodsh"
12323
12324         local ENOSPC=28
12325         local has_warning=false
12326
12327         rm -rf $DIR/$tdir
12328         mkdir -p $DIR/$tdir
12329
12330         # block size of mds1
12331         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12332         set_dir_limits $maxsize $((maxsize * 6 / 8))
12333         stack_trap "set_dir_limits 0 0"
12334         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12335         local dirsize=$(stat -c%s "$DIR/$tdir")
12336         local nfiles=0
12337         while (( $dirsize <= $maxsize )); do
12338                 $MCREATE $DIR/$tdir/file_base_$nfiles
12339                 rc=$?
12340                 # check two errors:
12341                 # ENOSPC for ext4 max_dir_size, which has been used since
12342                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12343                 if (( rc == ENOSPC )); then
12344                         set_dir_limits 0 0
12345                         echo "rc=$rc returned as expected after $nfiles files"
12346
12347                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12348                                 error "create failed w/o dir size limit"
12349
12350                         # messages may be rate limited if test is run repeatedly
12351                         check_mds_dmesg '"is approaching max"' ||
12352                                 echo "warning message should be output"
12353                         check_mds_dmesg '"has reached max"' ||
12354                                 echo "reached message should be output"
12355
12356                         dirsize=$(stat -c%s "$DIR/$tdir")
12357
12358                         [[ $dirsize -ge $maxsize ]] && return 0
12359                         error "dirsize $dirsize < $maxsize after $nfiles files"
12360                 elif (( rc != 0 )); then
12361                         break
12362                 fi
12363                 nfiles=$((nfiles + 1))
12364                 dirsize=$(stat -c%s "$DIR/$tdir")
12365         done
12366
12367         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12368 }
12369 run_test 129 "test directory size limit ========================"
12370
12371 OLDIFS="$IFS"
12372 cleanup_130() {
12373         trap 0
12374         IFS="$OLDIFS"
12375 }
12376
12377 test_130a() {
12378         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12379         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12380
12381         trap cleanup_130 EXIT RETURN
12382
12383         local fm_file=$DIR/$tfile
12384         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12385         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12386                 error "dd failed for $fm_file"
12387
12388         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12389         filefrag -ves $fm_file
12390         RC=$?
12391         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12392                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12393         [ $RC != 0 ] && error "filefrag $fm_file failed"
12394
12395         filefrag_op=$(filefrag -ve -k $fm_file |
12396                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12397         lun=$($LFS getstripe -i $fm_file)
12398
12399         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12400         IFS=$'\n'
12401         tot_len=0
12402         for line in $filefrag_op
12403         do
12404                 frag_lun=`echo $line | cut -d: -f5`
12405                 ext_len=`echo $line | cut -d: -f4`
12406                 if (( $frag_lun != $lun )); then
12407                         cleanup_130
12408                         error "FIEMAP on 1-stripe file($fm_file) failed"
12409                         return
12410                 fi
12411                 (( tot_len += ext_len ))
12412         done
12413
12414         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12415                 cleanup_130
12416                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12417                 return
12418         fi
12419
12420         cleanup_130
12421
12422         echo "FIEMAP on single striped file succeeded"
12423 }
12424 run_test 130a "FIEMAP (1-stripe file)"
12425
12426 test_130b() {
12427         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12428
12429         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12430         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12431
12432         trap cleanup_130 EXIT RETURN
12433
12434         local fm_file=$DIR/$tfile
12435         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12436                         error "setstripe on $fm_file"
12437         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12438                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12439
12440         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12441                 error "dd failed on $fm_file"
12442
12443         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12444         filefrag_op=$(filefrag -ve -k $fm_file |
12445                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12446
12447         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12448                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12449
12450         IFS=$'\n'
12451         tot_len=0
12452         num_luns=1
12453         for line in $filefrag_op
12454         do
12455                 frag_lun=$(echo $line | cut -d: -f5 |
12456                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12457                 ext_len=$(echo $line | cut -d: -f4)
12458                 if (( $frag_lun != $last_lun )); then
12459                         if (( tot_len != 1024 )); then
12460                                 cleanup_130
12461                                 error "FIEMAP on $fm_file failed; returned " \
12462                                 "len $tot_len for OST $last_lun instead of 1024"
12463                                 return
12464                         else
12465                                 (( num_luns += 1 ))
12466                                 tot_len=0
12467                         fi
12468                 fi
12469                 (( tot_len += ext_len ))
12470                 last_lun=$frag_lun
12471         done
12472         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12473                 cleanup_130
12474                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12475                         "luns or wrong len for OST $last_lun"
12476                 return
12477         fi
12478
12479         cleanup_130
12480
12481         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12482 }
12483 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12484
12485 test_130c() {
12486         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12487
12488         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12489         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12490
12491         trap cleanup_130 EXIT RETURN
12492
12493         local fm_file=$DIR/$tfile
12494         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12495         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12496                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12497
12498         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12499                         error "dd failed on $fm_file"
12500
12501         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12502         filefrag_op=$(filefrag -ve -k $fm_file |
12503                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12504
12505         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12506                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12507
12508         IFS=$'\n'
12509         tot_len=0
12510         num_luns=1
12511         for line in $filefrag_op
12512         do
12513                 frag_lun=$(echo $line | cut -d: -f5 |
12514                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12515                 ext_len=$(echo $line | cut -d: -f4)
12516                 if (( $frag_lun != $last_lun )); then
12517                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12518                         if (( logical != 512 )); then
12519                                 cleanup_130
12520                                 error "FIEMAP on $fm_file failed; returned " \
12521                                 "logical start for lun $logical instead of 512"
12522                                 return
12523                         fi
12524                         if (( tot_len != 512 )); then
12525                                 cleanup_130
12526                                 error "FIEMAP on $fm_file failed; returned " \
12527                                 "len $tot_len for OST $last_lun instead of 1024"
12528                                 return
12529                         else
12530                                 (( num_luns += 1 ))
12531                                 tot_len=0
12532                         fi
12533                 fi
12534                 (( tot_len += ext_len ))
12535                 last_lun=$frag_lun
12536         done
12537         if (( num_luns != 2 || tot_len != 512 )); then
12538                 cleanup_130
12539                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12540                         "luns or wrong len for OST $last_lun"
12541                 return
12542         fi
12543
12544         cleanup_130
12545
12546         echo "FIEMAP on 2-stripe file with hole succeeded"
12547 }
12548 run_test 130c "FIEMAP (2-stripe file with hole)"
12549
12550 test_130d() {
12551         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12552
12553         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12554         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12555
12556         trap cleanup_130 EXIT RETURN
12557
12558         local fm_file=$DIR/$tfile
12559         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12560                         error "setstripe on $fm_file"
12561         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12562                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12563
12564         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12565         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12566                 error "dd failed on $fm_file"
12567
12568         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12569         filefrag_op=$(filefrag -ve -k $fm_file |
12570                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12571
12572         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12573                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12574
12575         IFS=$'\n'
12576         tot_len=0
12577         num_luns=1
12578         for line in $filefrag_op
12579         do
12580                 frag_lun=$(echo $line | cut -d: -f5 |
12581                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12582                 ext_len=$(echo $line | cut -d: -f4)
12583                 if (( $frag_lun != $last_lun )); then
12584                         if (( tot_len != 1024 )); then
12585                                 cleanup_130
12586                                 error "FIEMAP on $fm_file failed; returned " \
12587                                 "len $tot_len for OST $last_lun instead of 1024"
12588                                 return
12589                         else
12590                                 (( num_luns += 1 ))
12591                                 tot_len=0
12592                         fi
12593                 fi
12594                 (( tot_len += ext_len ))
12595                 last_lun=$frag_lun
12596         done
12597         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12598                 cleanup_130
12599                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12600                         "luns or wrong len for OST $last_lun"
12601                 return
12602         fi
12603
12604         cleanup_130
12605
12606         echo "FIEMAP on N-stripe file succeeded"
12607 }
12608 run_test 130d "FIEMAP (N-stripe file)"
12609
12610 test_130e() {
12611         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12612
12613         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12614         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12615
12616         trap cleanup_130 EXIT RETURN
12617
12618         local fm_file=$DIR/$tfile
12619         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12620         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12621                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12622
12623         NUM_BLKS=512
12624         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12625         for ((i = 0; i < $NUM_BLKS; i++))
12626         do
12627                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12628         done
12629
12630         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12631         filefrag_op=$(filefrag -ve -k $fm_file |
12632                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12633
12634         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12635                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12636
12637         IFS=$'\n'
12638         tot_len=0
12639         num_luns=1
12640         for line in $filefrag_op
12641         do
12642                 frag_lun=$(echo $line | cut -d: -f5 |
12643                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12644                 ext_len=$(echo $line | cut -d: -f4)
12645                 if (( $frag_lun != $last_lun )); then
12646                         if (( tot_len != $EXPECTED_LEN )); then
12647                                 cleanup_130
12648                                 error "FIEMAP on $fm_file failed; returned " \
12649                                 "len $tot_len for OST $last_lun instead " \
12650                                 "of $EXPECTED_LEN"
12651                                 return
12652                         else
12653                                 (( num_luns += 1 ))
12654                                 tot_len=0
12655                         fi
12656                 fi
12657                 (( tot_len += ext_len ))
12658                 last_lun=$frag_lun
12659         done
12660         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12661                 cleanup_130
12662                 error "FIEMAP on $fm_file failed; returned wrong number " \
12663                         "of luns or wrong len for OST $last_lun"
12664                 return
12665         fi
12666
12667         cleanup_130
12668
12669         echo "FIEMAP with continuation calls succeeded"
12670 }
12671 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12672
12673 test_130f() {
12674         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12675         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12676
12677         local fm_file=$DIR/$tfile
12678         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12679                 error "multiop create with lov_delay_create on $fm_file"
12680
12681         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12682         filefrag_extents=$(filefrag -vek $fm_file |
12683                            awk '/extents? found/ { print $2 }')
12684         if [[ "$filefrag_extents" != "0" ]]; then
12685                 error "FIEMAP on $fm_file failed; " \
12686                       "returned $filefrag_extents expected 0"
12687         fi
12688
12689         rm -f $fm_file
12690 }
12691 run_test 130f "FIEMAP (unstriped file)"
12692
12693 # Test for writev/readv
12694 test_131a() {
12695         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12696                 error "writev test failed"
12697         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12698                 error "readv failed"
12699         rm -f $DIR/$tfile
12700 }
12701 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12702
12703 test_131b() {
12704         local fsize=$((524288 + 1048576 + 1572864))
12705         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12706                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12707                         error "append writev test failed"
12708
12709         ((fsize += 1572864 + 1048576))
12710         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12711                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12712                         error "append writev test failed"
12713         rm -f $DIR/$tfile
12714 }
12715 run_test 131b "test append writev"
12716
12717 test_131c() {
12718         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12719         error "NOT PASS"
12720 }
12721 run_test 131c "test read/write on file w/o objects"
12722
12723 test_131d() {
12724         rwv -f $DIR/$tfile -w -n 1 1572864
12725         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12726         if [ "$NOB" != 1572864 ]; then
12727                 error "Short read filed: read $NOB bytes instead of 1572864"
12728         fi
12729         rm -f $DIR/$tfile
12730 }
12731 run_test 131d "test short read"
12732
12733 test_131e() {
12734         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12735         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12736         error "read hitting hole failed"
12737         rm -f $DIR/$tfile
12738 }
12739 run_test 131e "test read hitting hole"
12740
12741 check_stats() {
12742         local facet=$1
12743         local op=$2
12744         local want=${3:-0}
12745         local res
12746
12747         case $facet in
12748         mds*) res=$(do_facet $facet \
12749                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12750                  ;;
12751         ost*) res=$(do_facet $facet \
12752                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12753                  ;;
12754         *) error "Wrong facet '$facet'" ;;
12755         esac
12756         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12757         # if the argument $3 is zero, it means any stat increment is ok.
12758         if [[ $want -gt 0 ]]; then
12759                 local count=$(echo $res | awk '{ print $2 }')
12760                 [[ $count -ne $want ]] &&
12761                         error "The $op counter on $facet is $count, not $want"
12762         fi
12763 }
12764
12765 test_133a() {
12766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12767         remote_ost_nodsh && skip "remote OST with nodsh"
12768         remote_mds_nodsh && skip "remote MDS with nodsh"
12769         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12770                 skip_env "MDS doesn't support rename stats"
12771
12772         local testdir=$DIR/${tdir}/stats_testdir
12773
12774         mkdir -p $DIR/${tdir}
12775
12776         # clear stats.
12777         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12778         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12779
12780         # verify mdt stats first.
12781         mkdir ${testdir} || error "mkdir failed"
12782         check_stats $SINGLEMDS "mkdir" 1
12783         touch ${testdir}/${tfile} || error "touch failed"
12784         check_stats $SINGLEMDS "open" 1
12785         check_stats $SINGLEMDS "close" 1
12786         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12787                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12788                 check_stats $SINGLEMDS "mknod" 2
12789         }
12790         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12791         check_stats $SINGLEMDS "unlink" 1
12792         rm -f ${testdir}/${tfile} || error "file remove failed"
12793         check_stats $SINGLEMDS "unlink" 2
12794
12795         # remove working dir and check mdt stats again.
12796         rmdir ${testdir} || error "rmdir failed"
12797         check_stats $SINGLEMDS "rmdir" 1
12798
12799         local testdir1=$DIR/${tdir}/stats_testdir1
12800         mkdir -p ${testdir}
12801         mkdir -p ${testdir1}
12802         touch ${testdir1}/test1
12803         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12804         check_stats $SINGLEMDS "crossdir_rename" 1
12805
12806         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12807         check_stats $SINGLEMDS "samedir_rename" 1
12808
12809         rm -rf $DIR/${tdir}
12810 }
12811 run_test 133a "Verifying MDT stats ========================================"
12812
12813 test_133b() {
12814         local res
12815
12816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12817         remote_ost_nodsh && skip "remote OST with nodsh"
12818         remote_mds_nodsh && skip "remote MDS with nodsh"
12819
12820         local testdir=$DIR/${tdir}/stats_testdir
12821
12822         mkdir -p ${testdir} || error "mkdir failed"
12823         touch ${testdir}/${tfile} || error "touch failed"
12824         cancel_lru_locks mdc
12825
12826         # clear stats.
12827         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12828         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12829
12830         # extra mdt stats verification.
12831         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12832         check_stats $SINGLEMDS "setattr" 1
12833         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12834         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12835         then            # LU-1740
12836                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12837                 check_stats $SINGLEMDS "getattr" 1
12838         fi
12839         rm -rf $DIR/${tdir}
12840
12841         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12842         # so the check below is not reliable
12843         [ $MDSCOUNT -eq 1 ] || return 0
12844
12845         # Sleep to avoid a cached response.
12846         #define OBD_STATFS_CACHE_SECONDS 1
12847         sleep 2
12848         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12849         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12850         $LFS df || error "lfs failed"
12851         check_stats $SINGLEMDS "statfs" 1
12852
12853         # check aggregated statfs (LU-10018)
12854         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12855                 return 0
12856         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12857                 return 0
12858         sleep 2
12859         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12860         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12861         df $DIR
12862         check_stats $SINGLEMDS "statfs" 1
12863
12864         # We want to check that the client didn't send OST_STATFS to
12865         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12866         # extra care is needed here.
12867         if remote_mds; then
12868                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12869                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12870
12871                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12872                 [ "$res" ] && error "OST got STATFS"
12873         fi
12874
12875         return 0
12876 }
12877 run_test 133b "Verifying extra MDT stats =================================="
12878
12879 test_133c() {
12880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12881         remote_ost_nodsh && skip "remote OST with nodsh"
12882         remote_mds_nodsh && skip "remote MDS with nodsh"
12883
12884         local testdir=$DIR/$tdir/stats_testdir
12885
12886         test_mkdir -p $testdir
12887
12888         # verify obdfilter stats.
12889         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12890         sync
12891         cancel_lru_locks osc
12892         wait_delete_completed
12893
12894         # clear stats.
12895         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12896         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12897
12898         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12899                 error "dd failed"
12900         sync
12901         cancel_lru_locks osc
12902         check_stats ost1 "write" 1
12903
12904         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12905         check_stats ost1 "read" 1
12906
12907         > $testdir/$tfile || error "truncate failed"
12908         check_stats ost1 "punch" 1
12909
12910         rm -f $testdir/$tfile || error "file remove failed"
12911         wait_delete_completed
12912         check_stats ost1 "destroy" 1
12913
12914         rm -rf $DIR/$tdir
12915 }
12916 run_test 133c "Verifying OST stats ========================================"
12917
12918 order_2() {
12919         local value=$1
12920         local orig=$value
12921         local order=1
12922
12923         while [ $value -ge 2 ]; do
12924                 order=$((order*2))
12925                 value=$((value/2))
12926         done
12927
12928         if [ $orig -gt $order ]; then
12929                 order=$((order*2))
12930         fi
12931         echo $order
12932 }
12933
12934 size_in_KMGT() {
12935     local value=$1
12936     local size=('K' 'M' 'G' 'T');
12937     local i=0
12938     local size_string=$value
12939
12940     while [ $value -ge 1024 ]; do
12941         if [ $i -gt 3 ]; then
12942             #T is the biggest unit we get here, if that is bigger,
12943             #just return XXXT
12944             size_string=${value}T
12945             break
12946         fi
12947         value=$((value >> 10))
12948         if [ $value -lt 1024 ]; then
12949             size_string=${value}${size[$i]}
12950             break
12951         fi
12952         i=$((i + 1))
12953     done
12954
12955     echo $size_string
12956 }
12957
12958 get_rename_size() {
12959         local size=$1
12960         local context=${2:-.}
12961         local sample=$(do_facet $SINGLEMDS $LCTL \
12962                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12963                 grep -A1 $context |
12964                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12965         echo $sample
12966 }
12967
12968 test_133d() {
12969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12970         remote_ost_nodsh && skip "remote OST with nodsh"
12971         remote_mds_nodsh && skip "remote MDS with nodsh"
12972         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12973                 skip_env "MDS doesn't support rename stats"
12974
12975         local testdir1=$DIR/${tdir}/stats_testdir1
12976         local testdir2=$DIR/${tdir}/stats_testdir2
12977         mkdir -p $DIR/${tdir}
12978
12979         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12980
12981         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12982         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12983
12984         createmany -o $testdir1/test 512 || error "createmany failed"
12985
12986         # check samedir rename size
12987         mv ${testdir1}/test0 ${testdir1}/test_0
12988
12989         local testdir1_size=$(ls -l $DIR/${tdir} |
12990                 awk '/stats_testdir1/ {print $5}')
12991         local testdir2_size=$(ls -l $DIR/${tdir} |
12992                 awk '/stats_testdir2/ {print $5}')
12993
12994         testdir1_size=$(order_2 $testdir1_size)
12995         testdir2_size=$(order_2 $testdir2_size)
12996
12997         testdir1_size=$(size_in_KMGT $testdir1_size)
12998         testdir2_size=$(size_in_KMGT $testdir2_size)
12999
13000         echo "source rename dir size: ${testdir1_size}"
13001         echo "target rename dir size: ${testdir2_size}"
13002
13003         local cmd="do_facet $SINGLEMDS $LCTL "
13004         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13005
13006         eval $cmd || error "$cmd failed"
13007         local samedir=$($cmd | grep 'same_dir')
13008         local same_sample=$(get_rename_size $testdir1_size)
13009         [ -z "$samedir" ] && error "samedir_rename_size count error"
13010         [[ $same_sample -eq 1 ]] ||
13011                 error "samedir_rename_size error $same_sample"
13012         echo "Check same dir rename stats success"
13013
13014         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13015
13016         # check crossdir rename size
13017         mv ${testdir1}/test_0 ${testdir2}/test_0
13018
13019         testdir1_size=$(ls -l $DIR/${tdir} |
13020                 awk '/stats_testdir1/ {print $5}')
13021         testdir2_size=$(ls -l $DIR/${tdir} |
13022                 awk '/stats_testdir2/ {print $5}')
13023
13024         testdir1_size=$(order_2 $testdir1_size)
13025         testdir2_size=$(order_2 $testdir2_size)
13026
13027         testdir1_size=$(size_in_KMGT $testdir1_size)
13028         testdir2_size=$(size_in_KMGT $testdir2_size)
13029
13030         echo "source rename dir size: ${testdir1_size}"
13031         echo "target rename dir size: ${testdir2_size}"
13032
13033         eval $cmd || error "$cmd failed"
13034         local crossdir=$($cmd | grep 'crossdir')
13035         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13036         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13037         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13038         [[ $src_sample -eq 1 ]] ||
13039                 error "crossdir_rename_size error $src_sample"
13040         [[ $tgt_sample -eq 1 ]] ||
13041                 error "crossdir_rename_size error $tgt_sample"
13042         echo "Check cross dir rename stats success"
13043         rm -rf $DIR/${tdir}
13044 }
13045 run_test 133d "Verifying rename_stats ========================================"
13046
13047 test_133e() {
13048         remote_mds_nodsh && skip "remote MDS with nodsh"
13049         remote_ost_nodsh && skip "remote OST with nodsh"
13050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13051
13052         local testdir=$DIR/${tdir}/stats_testdir
13053         local ctr f0 f1 bs=32768 count=42 sum
13054
13055         mkdir -p ${testdir} || error "mkdir failed"
13056
13057         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13058
13059         for ctr in {write,read}_bytes; do
13060                 sync
13061                 cancel_lru_locks osc
13062
13063                 do_facet ost1 $LCTL set_param -n \
13064                         "obdfilter.*.exports.clear=clear"
13065
13066                 if [ $ctr = write_bytes ]; then
13067                         f0=/dev/zero
13068                         f1=${testdir}/${tfile}
13069                 else
13070                         f0=${testdir}/${tfile}
13071                         f1=/dev/null
13072                 fi
13073
13074                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13075                         error "dd failed"
13076                 sync
13077                 cancel_lru_locks osc
13078
13079                 sum=$(do_facet ost1 $LCTL get_param \
13080                         "obdfilter.*.exports.*.stats" |
13081                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13082                                 $1 == ctr { sum += $7 }
13083                                 END { printf("%0.0f", sum) }')
13084
13085                 if ((sum != bs * count)); then
13086                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13087                 fi
13088         done
13089
13090         rm -rf $DIR/${tdir}
13091 }
13092 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13093
13094 test_133f() {
13095         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13096                 skip "too old lustre for get_param -R ($facet_ver)"
13097
13098         # verifying readability.
13099         $LCTL get_param -R '*' &> /dev/null
13100
13101         # Verifing writability with badarea_io.
13102         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13103                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13104                 error "client badarea_io failed"
13105
13106         # remount the FS in case writes/reads /proc break the FS
13107         cleanup || error "failed to unmount"
13108         setup || error "failed to setup"
13109 }
13110 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13111
13112 test_133g() {
13113         remote_mds_nodsh && skip "remote MDS with nodsh"
13114         remote_ost_nodsh && skip "remote OST with nodsh"
13115
13116         local facet
13117         for facet in mds1 ost1; do
13118                 local facet_ver=$(lustre_version_code $facet)
13119                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13120                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13121                 else
13122                         log "$facet: too old lustre for get_param -R"
13123                 fi
13124                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13125                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13126                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13127                                 xargs badarea_io" ||
13128                                         error "$facet badarea_io failed"
13129                 else
13130                         skip_noexit "$facet: too old lustre for get_param -R"
13131                 fi
13132         done
13133
13134         # remount the FS in case writes/reads /proc break the FS
13135         cleanup || error "failed to unmount"
13136         setup || error "failed to setup"
13137 }
13138 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13139
13140 test_133h() {
13141         remote_mds_nodsh && skip "remote MDS with nodsh"
13142         remote_ost_nodsh && skip "remote OST with nodsh"
13143         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13144                 skip "Need MDS version at least 2.9.54"
13145
13146         local facet
13147         for facet in client mds1 ost1; do
13148                 # Get the list of files that are missing the terminating newline
13149                 local plist=$(do_facet $facet
13150                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13151                 local ent
13152                 for ent in $plist; do
13153                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13154                                 awk -v FS='\v' -v RS='\v\v' \
13155                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13156                                         print FILENAME}'" 2>/dev/null)
13157                         [ -z $missing ] || {
13158                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13159                                 error "file does not end with newline: $facet-$ent"
13160                         }
13161                 done
13162         done
13163 }
13164 run_test 133h "Proc files should end with newlines"
13165
13166 test_134a() {
13167         remote_mds_nodsh && skip "remote MDS with nodsh"
13168         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13169                 skip "Need MDS version at least 2.7.54"
13170
13171         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13172         cancel_lru_locks mdc
13173
13174         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13175         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13176         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13177
13178         local nr=1000
13179         createmany -o $DIR/$tdir/f $nr ||
13180                 error "failed to create $nr files in $DIR/$tdir"
13181         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13182
13183         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13184         do_facet mds1 $LCTL set_param fail_loc=0x327
13185         do_facet mds1 $LCTL set_param fail_val=500
13186         touch $DIR/$tdir/m
13187
13188         echo "sleep 10 seconds ..."
13189         sleep 10
13190         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13191
13192         do_facet mds1 $LCTL set_param fail_loc=0
13193         do_facet mds1 $LCTL set_param fail_val=0
13194         [ $lck_cnt -lt $unused ] ||
13195                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13196
13197         rm $DIR/$tdir/m
13198         unlinkmany $DIR/$tdir/f $nr
13199 }
13200 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13201
13202 test_134b() {
13203         remote_mds_nodsh && skip "remote MDS with nodsh"
13204         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13205                 skip "Need MDS version at least 2.7.54"
13206
13207         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13208         cancel_lru_locks mdc
13209
13210         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13211                         ldlm.lock_reclaim_threshold_mb)
13212         # disable reclaim temporarily
13213         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13214
13215         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13216         do_facet mds1 $LCTL set_param fail_loc=0x328
13217         do_facet mds1 $LCTL set_param fail_val=500
13218
13219         $LCTL set_param debug=+trace
13220
13221         local nr=600
13222         createmany -o $DIR/$tdir/f $nr &
13223         local create_pid=$!
13224
13225         echo "Sleep $TIMEOUT seconds ..."
13226         sleep $TIMEOUT
13227         if ! ps -p $create_pid  > /dev/null 2>&1; then
13228                 do_facet mds1 $LCTL set_param fail_loc=0
13229                 do_facet mds1 $LCTL set_param fail_val=0
13230                 do_facet mds1 $LCTL set_param \
13231                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13232                 error "createmany finished incorrectly!"
13233         fi
13234         do_facet mds1 $LCTL set_param fail_loc=0
13235         do_facet mds1 $LCTL set_param fail_val=0
13236         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13237         wait $create_pid || return 1
13238
13239         unlinkmany $DIR/$tdir/f $nr
13240 }
13241 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13242
13243 test_135() {
13244         remote_mds_nodsh && skip "remote MDS with nodsh"
13245         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13246                 skip "Need MDS version at least 2.13.50"
13247         local fname
13248
13249         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13250
13251 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13252         #set only one record at plain llog
13253         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13254
13255         #fill already existed plain llog each 64767
13256         #wrapping whole catalog
13257         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13258
13259         createmany -o $DIR/$tdir/$tfile_ 64700
13260         for (( i = 0; i < 64700; i = i + 2 ))
13261         do
13262                 rm $DIR/$tdir/$tfile_$i &
13263                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13264                 local pid=$!
13265                 wait $pid
13266         done
13267
13268         #waiting osp synchronization
13269         wait_delete_completed
13270 }
13271 run_test 135 "Race catalog processing"
13272
13273 test_136() {
13274         remote_mds_nodsh && skip "remote MDS with nodsh"
13275         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13276                 skip "Need MDS version at least 2.13.50"
13277         local fname
13278
13279         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13280         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13281         #set only one record at plain llog
13282 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13283         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13284
13285         #fill already existed 2 plain llogs each 64767
13286         #wrapping whole catalog
13287         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13288         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13289         wait_delete_completed
13290
13291         createmany -o $DIR/$tdir/$tfile_ 10
13292         sleep 25
13293
13294         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13295         for (( i = 0; i < 10; i = i + 3 ))
13296         do
13297                 rm $DIR/$tdir/$tfile_$i &
13298                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13299                 local pid=$!
13300                 wait $pid
13301                 sleep 7
13302                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13303         done
13304
13305         #waiting osp synchronization
13306         wait_delete_completed
13307 }
13308 run_test 136 "Race catalog processing 2"
13309
13310 test_140() { #bug-17379
13311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13312
13313         test_mkdir $DIR/$tdir
13314         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13315         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13316
13317         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13318         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13319         local i=0
13320         while i=$((i + 1)); do
13321                 test_mkdir $i
13322                 cd $i || error "Changing to $i"
13323                 ln -s ../stat stat || error "Creating stat symlink"
13324                 # Read the symlink until ELOOP present,
13325                 # not LBUGing the system is considered success,
13326                 # we didn't overrun the stack.
13327                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13328                 if [ $ret -ne 0 ]; then
13329                         if [ $ret -eq 40 ]; then
13330                                 break  # -ELOOP
13331                         else
13332                                 error "Open stat symlink"
13333                                         return
13334                         fi
13335                 fi
13336         done
13337         i=$((i - 1))
13338         echo "The symlink depth = $i"
13339         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13340                 error "Invalid symlink depth"
13341
13342         # Test recursive symlink
13343         ln -s symlink_self symlink_self
13344         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13345         echo "open symlink_self returns $ret"
13346         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13347 }
13348 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13349
13350 test_150a() {
13351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13352
13353         local TF="$TMP/$tfile"
13354
13355         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13356         cp $TF $DIR/$tfile
13357         cancel_lru_locks $OSC
13358         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13359         remount_client $MOUNT
13360         df -P $MOUNT
13361         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13362
13363         $TRUNCATE $TF 6000
13364         $TRUNCATE $DIR/$tfile 6000
13365         cancel_lru_locks $OSC
13366         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13367
13368         echo "12345" >>$TF
13369         echo "12345" >>$DIR/$tfile
13370         cancel_lru_locks $OSC
13371         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13372
13373         echo "12345" >>$TF
13374         echo "12345" >>$DIR/$tfile
13375         cancel_lru_locks $OSC
13376         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13377
13378         rm -f $TF
13379         true
13380 }
13381 run_test 150a "truncate/append tests"
13382
13383 test_150b() {
13384         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13385         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13386                 skip "Need OST version at least 2.13.53"
13387         touch $DIR/$tfile
13388         check_fallocate $DIR/$tfile || error "fallocate failed"
13389 }
13390 run_test 150b "Verify fallocate (prealloc) functionality"
13391
13392 test_150c() {
13393         local bytes
13394         local want
13395
13396         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13397         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13398                 skip "Need OST version at least 2.13.53"
13399
13400         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13401         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13402         sync; sync_all_data
13403         cancel_lru_locks $OSC
13404         sleep 5
13405         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13406         want=$((OSTCOUNT * 1048576))
13407
13408         # Must allocate all requested space, not more than 5% extra
13409         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13410                 error "bytes $bytes is not $want"
13411 }
13412 run_test 150c "Verify fallocate Size and Blocks"
13413
13414 test_150d() {
13415         local bytes
13416         local want
13417
13418         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13419         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13420                 skip "Need OST version at least 2.13.53"
13421
13422         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13423         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13424         sync; sync_all_data
13425         cancel_lru_locks $OSC
13426         sleep 5
13427         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13428         want=$((OSTCOUNT * 1048576))
13429
13430         # Must allocate all requested space, not more than 5% extra
13431         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13432                 error "bytes $bytes is not $want"
13433 }
13434 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13435
13436 test_150e() {
13437         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13438         [ $OST1_VERSION -ge $(version_code 2.13.55) ] ||
13439                 skip "Need OST version at least 2.13.55"
13440
13441         echo "df before:"
13442         $LFS df
13443         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13444                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13445
13446         # Find OST with Minimum Size
13447         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13448                        sort -un | head -1)
13449
13450         # Get 90% of the available space
13451         local space=$(((min_size_ost * 90)/100 * OSTCOUNT))
13452
13453         fallocate -l${space}k $DIR/$tfile ||
13454                 error "fallocate ${space}k $DIR/$tfile failed"
13455         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13456
13457         # get size immediately after fallocate. This should be correctly
13458         # updated
13459         local size=$(stat -c '%s' $DIR/$tfile)
13460         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13461
13462         # Sleep for a while for statfs to get updated. And not pull from cache.
13463         sleep 2
13464
13465         echo "df after fallocate:"
13466         $LFS df
13467
13468         (( size / 1024 == space )) || error "size $size != requested $space"
13469         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13470                 error "used $used < space $space"
13471
13472         rm $DIR/$tfile || error "rm failed"
13473         sync
13474         wait_delete_completed
13475
13476         echo "df after unlink:"
13477         $LFS df
13478 }
13479 run_test 150e "Verify 90% of available OST space consumed by fallocate"
13480
13481 #LU-2902 roc_hit was not able to read all values from lproc
13482 function roc_hit_init() {
13483         local list=$(comma_list $(osts_nodes))
13484         local dir=$DIR/$tdir-check
13485         local file=$dir/$tfile
13486         local BEFORE
13487         local AFTER
13488         local idx
13489
13490         test_mkdir $dir
13491         #use setstripe to do a write to every ost
13492         for i in $(seq 0 $((OSTCOUNT-1))); do
13493                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13494                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13495                 idx=$(printf %04x $i)
13496                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13497                         awk '$1 == "cache_access" {sum += $7}
13498                                 END { printf("%0.0f", sum) }')
13499
13500                 cancel_lru_locks osc
13501                 cat $file >/dev/null
13502
13503                 AFTER=$(get_osd_param $list *OST*$idx stats |
13504                         awk '$1 == "cache_access" {sum += $7}
13505                                 END { printf("%0.0f", sum) }')
13506
13507                 echo BEFORE:$BEFORE AFTER:$AFTER
13508                 if ! let "AFTER - BEFORE == 4"; then
13509                         rm -rf $dir
13510                         error "roc_hit is not safe to use"
13511                 fi
13512                 rm $file
13513         done
13514
13515         rm -rf $dir
13516 }
13517
13518 function roc_hit() {
13519         local list=$(comma_list $(osts_nodes))
13520         echo $(get_osd_param $list '' stats |
13521                 awk '$1 == "cache_hit" {sum += $7}
13522                         END { printf("%0.0f", sum) }')
13523 }
13524
13525 function set_cache() {
13526         local on=1
13527
13528         if [ "$2" == "off" ]; then
13529                 on=0;
13530         fi
13531         local list=$(comma_list $(osts_nodes))
13532         set_osd_param $list '' $1_cache_enable $on
13533
13534         cancel_lru_locks osc
13535 }
13536
13537 test_151() {
13538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13539         remote_ost_nodsh && skip "remote OST with nodsh"
13540
13541         local CPAGES=3
13542         local list=$(comma_list $(osts_nodes))
13543
13544         # check whether obdfilter is cache capable at all
13545         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13546                 skip "not cache-capable obdfilter"
13547         fi
13548
13549         # check cache is enabled on all obdfilters
13550         if get_osd_param $list '' read_cache_enable | grep 0; then
13551                 skip "oss cache is disabled"
13552         fi
13553
13554         set_osd_param $list '' writethrough_cache_enable 1
13555
13556         # check write cache is enabled on all obdfilters
13557         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13558                 skip "oss write cache is NOT enabled"
13559         fi
13560
13561         roc_hit_init
13562
13563         #define OBD_FAIL_OBD_NO_LRU  0x609
13564         do_nodes $list $LCTL set_param fail_loc=0x609
13565
13566         # pages should be in the case right after write
13567         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13568                 error "dd failed"
13569
13570         local BEFORE=$(roc_hit)
13571         cancel_lru_locks osc
13572         cat $DIR/$tfile >/dev/null
13573         local AFTER=$(roc_hit)
13574
13575         do_nodes $list $LCTL set_param fail_loc=0
13576
13577         if ! let "AFTER - BEFORE == CPAGES"; then
13578                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13579         fi
13580
13581         cancel_lru_locks osc
13582         # invalidates OST cache
13583         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13584         set_osd_param $list '' read_cache_enable 0
13585         cat $DIR/$tfile >/dev/null
13586
13587         # now data shouldn't be found in the cache
13588         BEFORE=$(roc_hit)
13589         cancel_lru_locks osc
13590         cat $DIR/$tfile >/dev/null
13591         AFTER=$(roc_hit)
13592         if let "AFTER - BEFORE != 0"; then
13593                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13594         fi
13595
13596         set_osd_param $list '' read_cache_enable 1
13597         rm -f $DIR/$tfile
13598 }
13599 run_test 151 "test cache on oss and controls ==============================="
13600
13601 test_152() {
13602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13603
13604         local TF="$TMP/$tfile"
13605
13606         # simulate ENOMEM during write
13607 #define OBD_FAIL_OST_NOMEM      0x226
13608         lctl set_param fail_loc=0x80000226
13609         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13610         cp $TF $DIR/$tfile
13611         sync || error "sync failed"
13612         lctl set_param fail_loc=0
13613
13614         # discard client's cache
13615         cancel_lru_locks osc
13616
13617         # simulate ENOMEM during read
13618         lctl set_param fail_loc=0x80000226
13619         cmp $TF $DIR/$tfile || error "cmp failed"
13620         lctl set_param fail_loc=0
13621
13622         rm -f $TF
13623 }
13624 run_test 152 "test read/write with enomem ============================"
13625
13626 test_153() {
13627         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13628 }
13629 run_test 153 "test if fdatasync does not crash ======================="
13630
13631 dot_lustre_fid_permission_check() {
13632         local fid=$1
13633         local ffid=$MOUNT/.lustre/fid/$fid
13634         local test_dir=$2
13635
13636         echo "stat fid $fid"
13637         stat $ffid > /dev/null || error "stat $ffid failed."
13638         echo "touch fid $fid"
13639         touch $ffid || error "touch $ffid failed."
13640         echo "write to fid $fid"
13641         cat /etc/hosts > $ffid || error "write $ffid failed."
13642         echo "read fid $fid"
13643         diff /etc/hosts $ffid || error "read $ffid failed."
13644         echo "append write to fid $fid"
13645         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13646         echo "rename fid $fid"
13647         mv $ffid $test_dir/$tfile.1 &&
13648                 error "rename $ffid to $tfile.1 should fail."
13649         touch $test_dir/$tfile.1
13650         mv $test_dir/$tfile.1 $ffid &&
13651                 error "rename $tfile.1 to $ffid should fail."
13652         rm -f $test_dir/$tfile.1
13653         echo "truncate fid $fid"
13654         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13655         echo "link fid $fid"
13656         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13657         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13658                 echo "setfacl fid $fid"
13659                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13660                 echo "getfacl fid $fid"
13661                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13662         fi
13663         echo "unlink fid $fid"
13664         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13665         echo "mknod fid $fid"
13666         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13667
13668         fid=[0xf00000400:0x1:0x0]
13669         ffid=$MOUNT/.lustre/fid/$fid
13670
13671         echo "stat non-exist fid $fid"
13672         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13673         echo "write to non-exist fid $fid"
13674         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13675         echo "link new fid $fid"
13676         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13677
13678         mkdir -p $test_dir/$tdir
13679         touch $test_dir/$tdir/$tfile
13680         fid=$($LFS path2fid $test_dir/$tdir)
13681         rc=$?
13682         [ $rc -ne 0 ] &&
13683                 error "error: could not get fid for $test_dir/$dir/$tfile."
13684
13685         ffid=$MOUNT/.lustre/fid/$fid
13686
13687         echo "ls $fid"
13688         ls $ffid > /dev/null || error "ls $ffid failed."
13689         echo "touch $fid/$tfile.1"
13690         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13691
13692         echo "touch $MOUNT/.lustre/fid/$tfile"
13693         touch $MOUNT/.lustre/fid/$tfile && \
13694                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13695
13696         echo "setxattr to $MOUNT/.lustre/fid"
13697         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13698
13699         echo "listxattr for $MOUNT/.lustre/fid"
13700         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13701
13702         echo "delxattr from $MOUNT/.lustre/fid"
13703         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13704
13705         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13706         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13707                 error "touch invalid fid should fail."
13708
13709         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13710         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13711                 error "touch non-normal fid should fail."
13712
13713         echo "rename $tdir to $MOUNT/.lustre/fid"
13714         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13715                 error "rename to $MOUNT/.lustre/fid should fail."
13716
13717         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13718         then            # LU-3547
13719                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13720                 local new_obf_mode=777
13721
13722                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13723                 chmod $new_obf_mode $DIR/.lustre/fid ||
13724                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13725
13726                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13727                 [ $obf_mode -eq $new_obf_mode ] ||
13728                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13729
13730                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13731                 chmod $old_obf_mode $DIR/.lustre/fid ||
13732                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13733         fi
13734
13735         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13736         fid=$($LFS path2fid $test_dir/$tfile-2)
13737
13738         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13739         then # LU-5424
13740                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13741                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13742                         error "create lov data thru .lustre failed"
13743         fi
13744         echo "cp /etc/passwd $test_dir/$tfile-2"
13745         cp /etc/passwd $test_dir/$tfile-2 ||
13746                 error "copy to $test_dir/$tfile-2 failed."
13747         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13748         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13749                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13750
13751         rm -rf $test_dir/tfile.lnk
13752         rm -rf $test_dir/$tfile-2
13753 }
13754
13755 test_154A() {
13756         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13757                 skip "Need MDS version at least 2.4.1"
13758
13759         local tf=$DIR/$tfile
13760         touch $tf
13761
13762         local fid=$($LFS path2fid $tf)
13763         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13764
13765         # check that we get the same pathname back
13766         local rootpath
13767         local found
13768         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13769                 echo "$rootpath $fid"
13770                 found=$($LFS fid2path $rootpath "$fid")
13771                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13772                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13773         done
13774
13775         # check wrong root path format
13776         rootpath=$MOUNT"_wrong"
13777         found=$($LFS fid2path $rootpath "$fid")
13778         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13779 }
13780 run_test 154A "lfs path2fid and fid2path basic checks"
13781
13782 test_154B() {
13783         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13784                 skip "Need MDS version at least 2.4.1"
13785
13786         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13787         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13788         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13789         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13790
13791         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13792         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13793
13794         # check that we get the same pathname
13795         echo "PFID: $PFID, name: $name"
13796         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13797         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13798         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13799                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13800
13801         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13802 }
13803 run_test 154B "verify the ll_decode_linkea tool"
13804
13805 test_154a() {
13806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13807         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13808         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13809                 skip "Need MDS version at least 2.2.51"
13810         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13811
13812         cp /etc/hosts $DIR/$tfile
13813
13814         fid=$($LFS path2fid $DIR/$tfile)
13815         rc=$?
13816         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13817
13818         dot_lustre_fid_permission_check "$fid" $DIR ||
13819                 error "dot lustre permission check $fid failed"
13820
13821         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13822
13823         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13824
13825         touch $MOUNT/.lustre/file &&
13826                 error "creation is not allowed under .lustre"
13827
13828         mkdir $MOUNT/.lustre/dir &&
13829                 error "mkdir is not allowed under .lustre"
13830
13831         rm -rf $DIR/$tfile
13832 }
13833 run_test 154a "Open-by-FID"
13834
13835 test_154b() {
13836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13837         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13838         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13839         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13840                 skip "Need MDS version at least 2.2.51"
13841
13842         local remote_dir=$DIR/$tdir/remote_dir
13843         local MDTIDX=1
13844         local rc=0
13845
13846         mkdir -p $DIR/$tdir
13847         $LFS mkdir -i $MDTIDX $remote_dir ||
13848                 error "create remote directory failed"
13849
13850         cp /etc/hosts $remote_dir/$tfile
13851
13852         fid=$($LFS path2fid $remote_dir/$tfile)
13853         rc=$?
13854         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13855
13856         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13857                 error "dot lustre permission check $fid failed"
13858         rm -rf $DIR/$tdir
13859 }
13860 run_test 154b "Open-by-FID for remote directory"
13861
13862 test_154c() {
13863         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13864                 skip "Need MDS version at least 2.4.1"
13865
13866         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13867         local FID1=$($LFS path2fid $DIR/$tfile.1)
13868         local FID2=$($LFS path2fid $DIR/$tfile.2)
13869         local FID3=$($LFS path2fid $DIR/$tfile.3)
13870
13871         local N=1
13872         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13873                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13874                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13875                 local want=FID$N
13876                 [ "$FID" = "${!want}" ] ||
13877                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13878                 N=$((N + 1))
13879         done
13880
13881         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13882         do
13883                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13884                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13885                 N=$((N + 1))
13886         done
13887 }
13888 run_test 154c "lfs path2fid and fid2path multiple arguments"
13889
13890 test_154d() {
13891         remote_mds_nodsh && skip "remote MDS with nodsh"
13892         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13893                 skip "Need MDS version at least 2.5.53"
13894
13895         if remote_mds; then
13896                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13897         else
13898                 nid="0@lo"
13899         fi
13900         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13901         local fd
13902         local cmd
13903
13904         rm -f $DIR/$tfile
13905         touch $DIR/$tfile
13906
13907         local fid=$($LFS path2fid $DIR/$tfile)
13908         # Open the file
13909         fd=$(free_fd)
13910         cmd="exec $fd<$DIR/$tfile"
13911         eval $cmd
13912         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13913         echo "$fid_list" | grep "$fid"
13914         rc=$?
13915
13916         cmd="exec $fd>/dev/null"
13917         eval $cmd
13918         if [ $rc -ne 0 ]; then
13919                 error "FID $fid not found in open files list $fid_list"
13920         fi
13921 }
13922 run_test 154d "Verify open file fid"
13923
13924 test_154e()
13925 {
13926         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13927                 skip "Need MDS version at least 2.6.50"
13928
13929         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13930                 error ".lustre returned by readdir"
13931         fi
13932 }
13933 run_test 154e ".lustre is not returned by readdir"
13934
13935 test_154f() {
13936         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13937
13938         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13939         test_mkdir -p -c1 $DIR/$tdir/d
13940         # test dirs inherit from its stripe
13941         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13942         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13943         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13944         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13945         touch $DIR/f
13946
13947         # get fid of parents
13948         local FID0=$($LFS path2fid $DIR/$tdir/d)
13949         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13950         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13951         local FID3=$($LFS path2fid $DIR)
13952
13953         # check that path2fid --parents returns expected <parent_fid>/name
13954         # 1) test for a directory (single parent)
13955         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13956         [ "$parent" == "$FID0/foo1" ] ||
13957                 error "expected parent: $FID0/foo1, got: $parent"
13958
13959         # 2) test for a file with nlink > 1 (multiple parents)
13960         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13961         echo "$parent" | grep -F "$FID1/$tfile" ||
13962                 error "$FID1/$tfile not returned in parent list"
13963         echo "$parent" | grep -F "$FID2/link" ||
13964                 error "$FID2/link not returned in parent list"
13965
13966         # 3) get parent by fid
13967         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13968         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13969         echo "$parent" | grep -F "$FID1/$tfile" ||
13970                 error "$FID1/$tfile not returned in parent list (by fid)"
13971         echo "$parent" | grep -F "$FID2/link" ||
13972                 error "$FID2/link not returned in parent list (by fid)"
13973
13974         # 4) test for entry in root directory
13975         parent=$($LFS path2fid --parents $DIR/f)
13976         echo "$parent" | grep -F "$FID3/f" ||
13977                 error "$FID3/f not returned in parent list"
13978
13979         # 5) test it on root directory
13980         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13981                 error "$MOUNT should not have parents"
13982
13983         # enable xattr caching and check that linkea is correctly updated
13984         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13985         save_lustre_params client "llite.*.xattr_cache" > $save
13986         lctl set_param llite.*.xattr_cache 1
13987
13988         # 6.1) linkea update on rename
13989         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13990
13991         # get parents by fid
13992         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13993         # foo1 should no longer be returned in parent list
13994         echo "$parent" | grep -F "$FID1" &&
13995                 error "$FID1 should no longer be in parent list"
13996         # the new path should appear
13997         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13998                 error "$FID2/$tfile.moved is not in parent list"
13999
14000         # 6.2) linkea update on unlink
14001         rm -f $DIR/$tdir/d/foo2/link
14002         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14003         # foo2/link should no longer be returned in parent list
14004         echo "$parent" | grep -F "$FID2/link" &&
14005                 error "$FID2/link should no longer be in parent list"
14006         true
14007
14008         rm -f $DIR/f
14009         restore_lustre_params < $save
14010         rm -f $save
14011 }
14012 run_test 154f "get parent fids by reading link ea"
14013
14014 test_154g()
14015 {
14016         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14017         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14018            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14019                 skip "Need MDS version at least 2.6.92"
14020
14021         mkdir -p $DIR/$tdir
14022         llapi_fid_test -d $DIR/$tdir
14023 }
14024 run_test 154g "various llapi FID tests"
14025
14026 test_155_small_load() {
14027     local temp=$TMP/$tfile
14028     local file=$DIR/$tfile
14029
14030     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14031         error "dd of=$temp bs=6096 count=1 failed"
14032     cp $temp $file
14033     cancel_lru_locks $OSC
14034     cmp $temp $file || error "$temp $file differ"
14035
14036     $TRUNCATE $temp 6000
14037     $TRUNCATE $file 6000
14038     cmp $temp $file || error "$temp $file differ (truncate1)"
14039
14040     echo "12345" >>$temp
14041     echo "12345" >>$file
14042     cmp $temp $file || error "$temp $file differ (append1)"
14043
14044     echo "12345" >>$temp
14045     echo "12345" >>$file
14046     cmp $temp $file || error "$temp $file differ (append2)"
14047
14048     rm -f $temp $file
14049     true
14050 }
14051
14052 test_155_big_load() {
14053         remote_ost_nodsh && skip "remote OST with nodsh"
14054
14055         local temp=$TMP/$tfile
14056         local file=$DIR/$tfile
14057
14058         free_min_max
14059         local cache_size=$(do_facet ost$((MAXI+1)) \
14060                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14061         local large_file_size=$((cache_size * 2))
14062
14063         echo "OSS cache size: $cache_size KB"
14064         echo "Large file size: $large_file_size KB"
14065
14066         [ $MAXV -le $large_file_size ] &&
14067                 skip_env "max available OST size needs > $large_file_size KB"
14068
14069         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14070
14071         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14072                 error "dd of=$temp bs=$large_file_size count=1k failed"
14073         cp $temp $file
14074         ls -lh $temp $file
14075         cancel_lru_locks osc
14076         cmp $temp $file || error "$temp $file differ"
14077
14078         rm -f $temp $file
14079         true
14080 }
14081
14082 save_writethrough() {
14083         local facets=$(get_facets OST)
14084
14085         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14086 }
14087
14088 test_155a() {
14089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14090
14091         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14092
14093         save_writethrough $p
14094
14095         set_cache read on
14096         set_cache writethrough on
14097         test_155_small_load
14098         restore_lustre_params < $p
14099         rm -f $p
14100 }
14101 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14102
14103 test_155b() {
14104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14105
14106         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14107
14108         save_writethrough $p
14109
14110         set_cache read on
14111         set_cache writethrough off
14112         test_155_small_load
14113         restore_lustre_params < $p
14114         rm -f $p
14115 }
14116 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14117
14118 test_155c() {
14119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14120
14121         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14122
14123         save_writethrough $p
14124
14125         set_cache read off
14126         set_cache writethrough on
14127         test_155_small_load
14128         restore_lustre_params < $p
14129         rm -f $p
14130 }
14131 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14132
14133 test_155d() {
14134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14135
14136         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14137
14138         save_writethrough $p
14139
14140         set_cache read off
14141         set_cache writethrough off
14142         test_155_small_load
14143         restore_lustre_params < $p
14144         rm -f $p
14145 }
14146 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14147
14148 test_155e() {
14149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14150
14151         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14152
14153         save_writethrough $p
14154
14155         set_cache read on
14156         set_cache writethrough on
14157         test_155_big_load
14158         restore_lustre_params < $p
14159         rm -f $p
14160 }
14161 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14162
14163 test_155f() {
14164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14165
14166         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14167
14168         save_writethrough $p
14169
14170         set_cache read on
14171         set_cache writethrough off
14172         test_155_big_load
14173         restore_lustre_params < $p
14174         rm -f $p
14175 }
14176 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14177
14178 test_155g() {
14179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14180
14181         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14182
14183         save_writethrough $p
14184
14185         set_cache read off
14186         set_cache writethrough on
14187         test_155_big_load
14188         restore_lustre_params < $p
14189         rm -f $p
14190 }
14191 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14192
14193 test_155h() {
14194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14195
14196         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14197
14198         save_writethrough $p
14199
14200         set_cache read off
14201         set_cache writethrough off
14202         test_155_big_load
14203         restore_lustre_params < $p
14204         rm -f $p
14205 }
14206 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14207
14208 test_156() {
14209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14210         remote_ost_nodsh && skip "remote OST with nodsh"
14211         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14212                 skip "stats not implemented on old servers"
14213         [ "$ost1_FSTYPE" = "zfs" ] &&
14214                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14215
14216         local CPAGES=3
14217         local BEFORE
14218         local AFTER
14219         local file="$DIR/$tfile"
14220         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14221
14222         save_writethrough $p
14223         roc_hit_init
14224
14225         log "Turn on read and write cache"
14226         set_cache read on
14227         set_cache writethrough on
14228
14229         log "Write data and read it back."
14230         log "Read should be satisfied from the cache."
14231         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14232         BEFORE=$(roc_hit)
14233         cancel_lru_locks osc
14234         cat $file >/dev/null
14235         AFTER=$(roc_hit)
14236         if ! let "AFTER - BEFORE == CPAGES"; then
14237                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14238         else
14239                 log "cache hits: before: $BEFORE, after: $AFTER"
14240         fi
14241
14242         log "Read again; it should be satisfied from the cache."
14243         BEFORE=$AFTER
14244         cancel_lru_locks osc
14245         cat $file >/dev/null
14246         AFTER=$(roc_hit)
14247         if ! let "AFTER - BEFORE == CPAGES"; then
14248                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14249         else
14250                 log "cache hits:: before: $BEFORE, after: $AFTER"
14251         fi
14252
14253         log "Turn off the read cache and turn on the write cache"
14254         set_cache read off
14255         set_cache writethrough on
14256
14257         log "Read again; it should be satisfied from the cache."
14258         BEFORE=$(roc_hit)
14259         cancel_lru_locks osc
14260         cat $file >/dev/null
14261         AFTER=$(roc_hit)
14262         if ! let "AFTER - BEFORE == CPAGES"; then
14263                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14264         else
14265                 log "cache hits:: before: $BEFORE, after: $AFTER"
14266         fi
14267
14268         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14269                 # > 2.12.56 uses pagecache if cached
14270                 log "Read again; it should not be satisfied from the cache."
14271                 BEFORE=$AFTER
14272                 cancel_lru_locks osc
14273                 cat $file >/dev/null
14274                 AFTER=$(roc_hit)
14275                 if ! let "AFTER - BEFORE == 0"; then
14276                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14277                 else
14278                         log "cache hits:: before: $BEFORE, after: $AFTER"
14279                 fi
14280         fi
14281
14282         log "Write data and read it back."
14283         log "Read should be satisfied from the cache."
14284         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14285         BEFORE=$(roc_hit)
14286         cancel_lru_locks osc
14287         cat $file >/dev/null
14288         AFTER=$(roc_hit)
14289         if ! let "AFTER - BEFORE == CPAGES"; then
14290                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14291         else
14292                 log "cache hits:: before: $BEFORE, after: $AFTER"
14293         fi
14294
14295         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14296                 # > 2.12.56 uses pagecache if cached
14297                 log "Read again; it should not be satisfied from the cache."
14298                 BEFORE=$AFTER
14299                 cancel_lru_locks osc
14300                 cat $file >/dev/null
14301                 AFTER=$(roc_hit)
14302                 if ! let "AFTER - BEFORE == 0"; then
14303                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14304                 else
14305                         log "cache hits:: before: $BEFORE, after: $AFTER"
14306                 fi
14307         fi
14308
14309         log "Turn off read and write cache"
14310         set_cache read off
14311         set_cache writethrough off
14312
14313         log "Write data and read it back"
14314         log "It should not be satisfied from the cache."
14315         rm -f $file
14316         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14317         cancel_lru_locks osc
14318         BEFORE=$(roc_hit)
14319         cat $file >/dev/null
14320         AFTER=$(roc_hit)
14321         if ! let "AFTER - BEFORE == 0"; then
14322                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14323         else
14324                 log "cache hits:: before: $BEFORE, after: $AFTER"
14325         fi
14326
14327         log "Turn on the read cache and turn off the write cache"
14328         set_cache read on
14329         set_cache writethrough off
14330
14331         log "Write data and read it back"
14332         log "It should not be satisfied from the cache."
14333         rm -f $file
14334         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14335         BEFORE=$(roc_hit)
14336         cancel_lru_locks osc
14337         cat $file >/dev/null
14338         AFTER=$(roc_hit)
14339         if ! let "AFTER - BEFORE == 0"; then
14340                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14341         else
14342                 log "cache hits:: before: $BEFORE, after: $AFTER"
14343         fi
14344
14345         log "Read again; it should be satisfied from the cache."
14346         BEFORE=$(roc_hit)
14347         cancel_lru_locks osc
14348         cat $file >/dev/null
14349         AFTER=$(roc_hit)
14350         if ! let "AFTER - BEFORE == CPAGES"; then
14351                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14352         else
14353                 log "cache hits:: before: $BEFORE, after: $AFTER"
14354         fi
14355
14356         restore_lustre_params < $p
14357         rm -f $p $file
14358 }
14359 run_test 156 "Verification of tunables"
14360
14361 test_160a() {
14362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14363         remote_mds_nodsh && skip "remote MDS with nodsh"
14364         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14365                 skip "Need MDS version at least 2.2.0"
14366
14367         changelog_register || error "changelog_register failed"
14368         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14369         changelog_users $SINGLEMDS | grep -q $cl_user ||
14370                 error "User $cl_user not found in changelog_users"
14371
14372         # change something
14373         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14374         changelog_clear 0 || error "changelog_clear failed"
14375         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14376         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14377         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14378         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14379         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14380         rm $DIR/$tdir/pics/desktop.jpg
14381
14382         changelog_dump | tail -10
14383
14384         echo "verifying changelog mask"
14385         changelog_chmask "-MKDIR"
14386         changelog_chmask "-CLOSE"
14387
14388         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14389         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14390
14391         changelog_chmask "+MKDIR"
14392         changelog_chmask "+CLOSE"
14393
14394         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14395         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14396
14397         changelog_dump | tail -10
14398         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14399         CLOSES=$(changelog_dump | grep -c "CLOSE")
14400         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14401         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14402
14403         # verify contents
14404         echo "verifying target fid"
14405         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14406         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14407         [ "$fidc" == "$fidf" ] ||
14408                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14409         echo "verifying parent fid"
14410         # The FID returned from the Changelog may be the directory shard on
14411         # a different MDT, and not the FID returned by path2fid on the parent.
14412         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14413         # since this is what will matter when recreating this file in the tree.
14414         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14415         local pathp=$($LFS fid2path $MOUNT "$fidp")
14416         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14417                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14418
14419         echo "getting records for $cl_user"
14420         changelog_users $SINGLEMDS
14421         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14422         local nclr=3
14423         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14424                 error "changelog_clear failed"
14425         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14426         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14427         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14428                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14429
14430         local min0_rec=$(changelog_users $SINGLEMDS |
14431                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14432         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14433                           awk '{ print $1; exit; }')
14434
14435         changelog_dump | tail -n 5
14436         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14437         [ $first_rec == $((min0_rec + 1)) ] ||
14438                 error "first index should be $min0_rec + 1 not $first_rec"
14439
14440         # LU-3446 changelog index reset on MDT restart
14441         local cur_rec1=$(changelog_users $SINGLEMDS |
14442                          awk '/^current.index:/ { print $NF }')
14443         changelog_clear 0 ||
14444                 error "clear all changelog records for $cl_user failed"
14445         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14446         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14447                 error "Fail to start $SINGLEMDS"
14448         local cur_rec2=$(changelog_users $SINGLEMDS |
14449                          awk '/^current.index:/ { print $NF }')
14450         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14451         [ $cur_rec1 == $cur_rec2 ] ||
14452                 error "current index should be $cur_rec1 not $cur_rec2"
14453
14454         echo "verifying users from this test are deregistered"
14455         changelog_deregister || error "changelog_deregister failed"
14456         changelog_users $SINGLEMDS | grep -q $cl_user &&
14457                 error "User '$cl_user' still in changelog_users"
14458
14459         # lctl get_param -n mdd.*.changelog_users
14460         # current index: 144
14461         # ID    index (idle seconds)
14462         # cl3   144 (2)
14463         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14464                 # this is the normal case where all users were deregistered
14465                 # make sure no new records are added when no users are present
14466                 local last_rec1=$(changelog_users $SINGLEMDS |
14467                                   awk '/^current.index:/ { print $NF }')
14468                 touch $DIR/$tdir/chloe
14469                 local last_rec2=$(changelog_users $SINGLEMDS |
14470                                   awk '/^current.index:/ { print $NF }')
14471                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14472                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14473         else
14474                 # any changelog users must be leftovers from a previous test
14475                 changelog_users $SINGLEMDS
14476                 echo "other changelog users; can't verify off"
14477         fi
14478 }
14479 run_test 160a "changelog sanity"
14480
14481 test_160b() { # LU-3587
14482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14483         remote_mds_nodsh && skip "remote MDS with nodsh"
14484         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14485                 skip "Need MDS version at least 2.2.0"
14486
14487         changelog_register || error "changelog_register failed"
14488         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14489         changelog_users $SINGLEMDS | grep -q $cl_user ||
14490                 error "User '$cl_user' not found in changelog_users"
14491
14492         local longname1=$(str_repeat a 255)
14493         local longname2=$(str_repeat b 255)
14494
14495         cd $DIR
14496         echo "creating very long named file"
14497         touch $longname1 || error "create of '$longname1' failed"
14498         echo "renaming very long named file"
14499         mv $longname1 $longname2
14500
14501         changelog_dump | grep RENME | tail -n 5
14502         rm -f $longname2
14503 }
14504 run_test 160b "Verify that very long rename doesn't crash in changelog"
14505
14506 test_160c() {
14507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14508         remote_mds_nodsh && skip "remote MDS with nodsh"
14509
14510         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14511                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14512                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14513                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14514
14515         local rc=0
14516
14517         # Registration step
14518         changelog_register || error "changelog_register failed"
14519
14520         rm -rf $DIR/$tdir
14521         mkdir -p $DIR/$tdir
14522         $MCREATE $DIR/$tdir/foo_160c
14523         changelog_chmask "-TRUNC"
14524         $TRUNCATE $DIR/$tdir/foo_160c 200
14525         changelog_chmask "+TRUNC"
14526         $TRUNCATE $DIR/$tdir/foo_160c 199
14527         changelog_dump | tail -n 5
14528         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14529         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14530 }
14531 run_test 160c "verify that changelog log catch the truncate event"
14532
14533 test_160d() {
14534         remote_mds_nodsh && skip "remote MDS with nodsh"
14535         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14537         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14538                 skip "Need MDS version at least 2.7.60"
14539
14540         # Registration step
14541         changelog_register || error "changelog_register failed"
14542
14543         mkdir -p $DIR/$tdir/migrate_dir
14544         changelog_clear 0 || error "changelog_clear failed"
14545
14546         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14547         changelog_dump | tail -n 5
14548         local migrates=$(changelog_dump | grep -c "MIGRT")
14549         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14550 }
14551 run_test 160d "verify that changelog log catch the migrate event"
14552
14553 test_160e() {
14554         remote_mds_nodsh && skip "remote MDS with nodsh"
14555
14556         # Create a user
14557         changelog_register || error "changelog_register failed"
14558
14559         # Delete a future user (expect fail)
14560         local MDT0=$(facet_svc $SINGLEMDS)
14561         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14562         local rc=$?
14563
14564         if [ $rc -eq 0 ]; then
14565                 error "Deleted non-existant user cl77"
14566         elif [ $rc -ne 2 ]; then
14567                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14568         fi
14569
14570         # Clear to a bad index (1 billion should be safe)
14571         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14572         rc=$?
14573
14574         if [ $rc -eq 0 ]; then
14575                 error "Successfully cleared to invalid CL index"
14576         elif [ $rc -ne 22 ]; then
14577                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14578         fi
14579 }
14580 run_test 160e "changelog negative testing (should return errors)"
14581
14582 test_160f() {
14583         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14584         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14585                 skip "Need MDS version at least 2.10.56"
14586
14587         local mdts=$(comma_list $(mdts_nodes))
14588
14589         # Create a user
14590         changelog_register || error "first changelog_register failed"
14591         changelog_register || error "second changelog_register failed"
14592         local cl_users
14593         declare -A cl_user1
14594         declare -A cl_user2
14595         local user_rec1
14596         local user_rec2
14597         local i
14598
14599         # generate some changelog records to accumulate on each MDT
14600         # use fnv1a because created files should be evenly distributed
14601         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14602                 error "test_mkdir $tdir failed"
14603         log "$(date +%s): creating first files"
14604         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14605                 error "create $DIR/$tdir/$tfile failed"
14606
14607         # check changelogs have been generated
14608         local start=$SECONDS
14609         local idle_time=$((MDSCOUNT * 5 + 5))
14610         local nbcl=$(changelog_dump | wc -l)
14611         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14612
14613         for param in "changelog_max_idle_time=$idle_time" \
14614                      "changelog_gc=1" \
14615                      "changelog_min_gc_interval=2" \
14616                      "changelog_min_free_cat_entries=3"; do
14617                 local MDT0=$(facet_svc $SINGLEMDS)
14618                 local var="${param%=*}"
14619                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14620
14621                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14622                 do_nodes $mdts $LCTL set_param mdd.*.$param
14623         done
14624
14625         # force cl_user2 to be idle (1st part), but also cancel the
14626         # cl_user1 records so that it is not evicted later in the test.
14627         local sleep1=$((idle_time / 2))
14628         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14629         sleep $sleep1
14630
14631         # simulate changelog catalog almost full
14632         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14633         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14634
14635         for i in $(seq $MDSCOUNT); do
14636                 cl_users=(${CL_USERS[mds$i]})
14637                 cl_user1[mds$i]="${cl_users[0]}"
14638                 cl_user2[mds$i]="${cl_users[1]}"
14639
14640                 [ -n "${cl_user1[mds$i]}" ] ||
14641                         error "mds$i: no user registered"
14642                 [ -n "${cl_user2[mds$i]}" ] ||
14643                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14644
14645                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14646                 [ -n "$user_rec1" ] ||
14647                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14648                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14649                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14650                 [ -n "$user_rec2" ] ||
14651                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14652                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14653                      "$user_rec1 + 2 == $user_rec2"
14654                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14655                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14656                               "$user_rec1 + 2, but is $user_rec2"
14657                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14658                 [ -n "$user_rec2" ] ||
14659                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14660                 [ $user_rec1 == $user_rec2 ] ||
14661                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14662                               "$user_rec1, but is $user_rec2"
14663         done
14664
14665         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14666         local sleep2=$((idle_time - (SECONDS - start) + 1))
14667         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14668         sleep $sleep2
14669
14670         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14671         # cl_user1 should be OK because it recently processed records.
14672         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14673         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14674                 error "create $DIR/$tdir/${tfile}b failed"
14675
14676         # ensure gc thread is done
14677         for i in $(mdts_nodes); do
14678                 wait_update $i \
14679                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14680                         error "$i: GC-thread not done"
14681         done
14682
14683         local first_rec
14684         for i in $(seq $MDSCOUNT); do
14685                 # check cl_user1 still registered
14686                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14687                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14688                 # check cl_user2 unregistered
14689                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14690                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14691
14692                 # check changelogs are present and starting at $user_rec1 + 1
14693                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14694                 [ -n "$user_rec1" ] ||
14695                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14696                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14697                             awk '{ print $1; exit; }')
14698
14699                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14700                 [ $((user_rec1 + 1)) == $first_rec ] ||
14701                         error "mds$i: first index should be $user_rec1 + 1, " \
14702                               "but is $first_rec"
14703         done
14704 }
14705 run_test 160f "changelog garbage collect (timestamped users)"
14706
14707 test_160g() {
14708         remote_mds_nodsh && skip "remote MDS with nodsh"
14709         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14710                 skip "Need MDS version at least 2.10.56"
14711
14712         local mdts=$(comma_list $(mdts_nodes))
14713
14714         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14715         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14716
14717         # Create a user
14718         changelog_register || error "first changelog_register failed"
14719         changelog_register || error "second changelog_register failed"
14720         local cl_users
14721         declare -A cl_user1
14722         declare -A cl_user2
14723         local user_rec1
14724         local user_rec2
14725         local i
14726
14727         # generate some changelog records to accumulate on each MDT
14728         # use fnv1a because created files should be evenly distributed
14729         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14730                 error "mkdir $tdir failed"
14731         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14732                 error "create $DIR/$tdir/$tfile failed"
14733
14734         # check changelogs have been generated
14735         local nbcl=$(changelog_dump | wc -l)
14736         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14737
14738         # reduce the max_idle_indexes value to make sure we exceed it
14739         max_ndx=$((nbcl / 2 - 1))
14740
14741         for param in "changelog_max_idle_indexes=$max_ndx" \
14742                      "changelog_gc=1" \
14743                      "changelog_min_gc_interval=2" \
14744                      "changelog_min_free_cat_entries=3"; do
14745                 local MDT0=$(facet_svc $SINGLEMDS)
14746                 local var="${param%=*}"
14747                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14748
14749                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14750                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14751                         error "unable to set mdd.*.$param"
14752         done
14753
14754         # simulate changelog catalog almost full
14755         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14756         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14757
14758         for i in $(seq $MDSCOUNT); do
14759                 cl_users=(${CL_USERS[mds$i]})
14760                 cl_user1[mds$i]="${cl_users[0]}"
14761                 cl_user2[mds$i]="${cl_users[1]}"
14762
14763                 [ -n "${cl_user1[mds$i]}" ] ||
14764                         error "mds$i: no user registered"
14765                 [ -n "${cl_user2[mds$i]}" ] ||
14766                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14767
14768                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14769                 [ -n "$user_rec1" ] ||
14770                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14771                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14772                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14773                 [ -n "$user_rec2" ] ||
14774                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14775                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14776                      "$user_rec1 + 2 == $user_rec2"
14777                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14778                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14779                               "$user_rec1 + 2, but is $user_rec2"
14780                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14781                 [ -n "$user_rec2" ] ||
14782                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14783                 [ $user_rec1 == $user_rec2 ] ||
14784                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14785                               "$user_rec1, but is $user_rec2"
14786         done
14787
14788         # ensure we are past the previous changelog_min_gc_interval set above
14789         sleep 2
14790
14791         # generate one more changelog to trigger fail_loc
14792         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14793                 error "create $DIR/$tdir/${tfile}bis failed"
14794
14795         # ensure gc thread is done
14796         for i in $(mdts_nodes); do
14797                 wait_update $i \
14798                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14799                         error "$i: GC-thread not done"
14800         done
14801
14802         local first_rec
14803         for i in $(seq $MDSCOUNT); do
14804                 # check cl_user1 still registered
14805                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14806                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14807                 # check cl_user2 unregistered
14808                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14809                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14810
14811                 # check changelogs are present and starting at $user_rec1 + 1
14812                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14813                 [ -n "$user_rec1" ] ||
14814                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14815                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14816                             awk '{ print $1; exit; }')
14817
14818                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14819                 [ $((user_rec1 + 1)) == $first_rec ] ||
14820                         error "mds$i: first index should be $user_rec1 + 1, " \
14821                               "but is $first_rec"
14822         done
14823 }
14824 run_test 160g "changelog garbage collect (old users)"
14825
14826 test_160h() {
14827         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14828         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14829                 skip "Need MDS version at least 2.10.56"
14830
14831         local mdts=$(comma_list $(mdts_nodes))
14832
14833         # Create a user
14834         changelog_register || error "first changelog_register failed"
14835         changelog_register || error "second changelog_register failed"
14836         local cl_users
14837         declare -A cl_user1
14838         declare -A cl_user2
14839         local user_rec1
14840         local user_rec2
14841         local i
14842
14843         # generate some changelog records to accumulate on each MDT
14844         # use fnv1a because created files should be evenly distributed
14845         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14846                 error "test_mkdir $tdir failed"
14847         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14848                 error "create $DIR/$tdir/$tfile failed"
14849
14850         # check changelogs have been generated
14851         local nbcl=$(changelog_dump | wc -l)
14852         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14853
14854         for param in "changelog_max_idle_time=10" \
14855                      "changelog_gc=1" \
14856                      "changelog_min_gc_interval=2"; do
14857                 local MDT0=$(facet_svc $SINGLEMDS)
14858                 local var="${param%=*}"
14859                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14860
14861                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14862                 do_nodes $mdts $LCTL set_param mdd.*.$param
14863         done
14864
14865         # force cl_user2 to be idle (1st part)
14866         sleep 9
14867
14868         for i in $(seq $MDSCOUNT); do
14869                 cl_users=(${CL_USERS[mds$i]})
14870                 cl_user1[mds$i]="${cl_users[0]}"
14871                 cl_user2[mds$i]="${cl_users[1]}"
14872
14873                 [ -n "${cl_user1[mds$i]}" ] ||
14874                         error "mds$i: no user registered"
14875                 [ -n "${cl_user2[mds$i]}" ] ||
14876                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14877
14878                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14879                 [ -n "$user_rec1" ] ||
14880                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14881                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14882                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14883                 [ -n "$user_rec2" ] ||
14884                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14885                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14886                      "$user_rec1 + 2 == $user_rec2"
14887                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14888                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14889                               "$user_rec1 + 2, but is $user_rec2"
14890                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14891                 [ -n "$user_rec2" ] ||
14892                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14893                 [ $user_rec1 == $user_rec2 ] ||
14894                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14895                               "$user_rec1, but is $user_rec2"
14896         done
14897
14898         # force cl_user2 to be idle (2nd part) and to reach
14899         # changelog_max_idle_time
14900         sleep 2
14901
14902         # force each GC-thread start and block then
14903         # one per MDT/MDD, set fail_val accordingly
14904         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14905         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14906
14907         # generate more changelogs to trigger fail_loc
14908         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14909                 error "create $DIR/$tdir/${tfile}bis failed"
14910
14911         # stop MDT to stop GC-thread, should be done in back-ground as it will
14912         # block waiting for the thread to be released and exit
14913         declare -A stop_pids
14914         for i in $(seq $MDSCOUNT); do
14915                 stop mds$i &
14916                 stop_pids[mds$i]=$!
14917         done
14918
14919         for i in $(mdts_nodes); do
14920                 local facet
14921                 local nb=0
14922                 local facets=$(facets_up_on_host $i)
14923
14924                 for facet in ${facets//,/ }; do
14925                         if [[ $facet == mds* ]]; then
14926                                 nb=$((nb + 1))
14927                         fi
14928                 done
14929                 # ensure each MDS's gc threads are still present and all in "R"
14930                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14931                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14932                         error "$i: expected $nb GC-thread"
14933                 wait_update $i \
14934                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14935                         "R" 20 ||
14936                         error "$i: GC-thread not found in R-state"
14937                 # check umounts of each MDT on MDS have reached kthread_stop()
14938                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14939                         error "$i: expected $nb umount"
14940                 wait_update $i \
14941                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14942                         error "$i: umount not found in D-state"
14943         done
14944
14945         # release all GC-threads
14946         do_nodes $mdts $LCTL set_param fail_loc=0
14947
14948         # wait for MDT stop to complete
14949         for i in $(seq $MDSCOUNT); do
14950                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14951         done
14952
14953         # XXX
14954         # may try to check if any orphan changelog records are present
14955         # via ldiskfs/zfs and llog_reader...
14956
14957         # re-start/mount MDTs
14958         for i in $(seq $MDSCOUNT); do
14959                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14960                         error "Fail to start mds$i"
14961         done
14962
14963         local first_rec
14964         for i in $(seq $MDSCOUNT); do
14965                 # check cl_user1 still registered
14966                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14967                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14968                 # check cl_user2 unregistered
14969                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14970                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14971
14972                 # check changelogs are present and starting at $user_rec1 + 1
14973                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14974                 [ -n "$user_rec1" ] ||
14975                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14976                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14977                             awk '{ print $1; exit; }')
14978
14979                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14980                 [ $((user_rec1 + 1)) == $first_rec ] ||
14981                         error "mds$i: first index should be $user_rec1 + 1, " \
14982                               "but is $first_rec"
14983         done
14984 }
14985 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14986               "during mount"
14987
14988 test_160i() {
14989
14990         local mdts=$(comma_list $(mdts_nodes))
14991
14992         changelog_register || error "first changelog_register failed"
14993
14994         # generate some changelog records to accumulate on each MDT
14995         # use fnv1a because created files should be evenly distributed
14996         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14997                 error "mkdir $tdir failed"
14998         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14999                 error "create $DIR/$tdir/$tfile failed"
15000
15001         # check changelogs have been generated
15002         local nbcl=$(changelog_dump | wc -l)
15003         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15004
15005         # simulate race between register and unregister
15006         # XXX as fail_loc is set per-MDS, with DNE configs the race
15007         # simulation will only occur for one MDT per MDS and for the
15008         # others the normal race scenario will take place
15009         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15010         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15011         do_nodes $mdts $LCTL set_param fail_val=1
15012
15013         # unregister 1st user
15014         changelog_deregister &
15015         local pid1=$!
15016         # wait some time for deregister work to reach race rdv
15017         sleep 2
15018         # register 2nd user
15019         changelog_register || error "2nd user register failed"
15020
15021         wait $pid1 || error "1st user deregister failed"
15022
15023         local i
15024         local last_rec
15025         declare -A LAST_REC
15026         for i in $(seq $MDSCOUNT); do
15027                 if changelog_users mds$i | grep "^cl"; then
15028                         # make sure new records are added with one user present
15029                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15030                                           awk '/^current.index:/ { print $NF }')
15031                 else
15032                         error "mds$i has no user registered"
15033                 fi
15034         done
15035
15036         # generate more changelog records to accumulate on each MDT
15037         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15038                 error "create $DIR/$tdir/${tfile}bis failed"
15039
15040         for i in $(seq $MDSCOUNT); do
15041                 last_rec=$(changelog_users $SINGLEMDS |
15042                            awk '/^current.index:/ { print $NF }')
15043                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15044                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15045                         error "changelogs are off on mds$i"
15046         done
15047 }
15048 run_test 160i "changelog user register/unregister race"
15049
15050 test_160j() {
15051         remote_mds_nodsh && skip "remote MDS with nodsh"
15052         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15053                 skip "Need MDS version at least 2.12.56"
15054
15055         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15056         stack_trap "umount $MOUNT2" EXIT
15057
15058         changelog_register || error "first changelog_register failed"
15059         stack_trap "changelog_deregister" EXIT
15060
15061         # generate some changelog
15062         # use fnv1a because created files should be evenly distributed
15063         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15064                 error "mkdir $tdir failed"
15065         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15066                 error "create $DIR/$tdir/${tfile}bis failed"
15067
15068         # open the changelog device
15069         exec 3>/dev/changelog-$FSNAME-MDT0000
15070         stack_trap "exec 3>&-" EXIT
15071         exec 4</dev/changelog-$FSNAME-MDT0000
15072         stack_trap "exec 4<&-" EXIT
15073
15074         # umount the first lustre mount
15075         umount $MOUNT
15076         stack_trap "mount_client $MOUNT" EXIT
15077
15078         # read changelog
15079         cat <&4 >/dev/null || error "read changelog failed"
15080
15081         # clear changelog
15082         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15083         changelog_users $SINGLEMDS | grep -q $cl_user ||
15084                 error "User $cl_user not found in changelog_users"
15085
15086         printf 'clear:'$cl_user':0' >&3
15087 }
15088 run_test 160j "client can be umounted  while its chanangelog is being used"
15089
15090 test_160k() {
15091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15092         remote_mds_nodsh && skip "remote MDS with nodsh"
15093
15094         mkdir -p $DIR/$tdir/1/1
15095
15096         changelog_register || error "changelog_register failed"
15097         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15098
15099         changelog_users $SINGLEMDS | grep -q $cl_user ||
15100                 error "User '$cl_user' not found in changelog_users"
15101 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15102         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15103         rmdir $DIR/$tdir/1/1 & sleep 1
15104         mkdir $DIR/$tdir/2
15105         touch $DIR/$tdir/2/2
15106         rm -rf $DIR/$tdir/2
15107
15108         wait
15109         sleep 4
15110
15111         changelog_dump | grep rmdir || error "rmdir not recorded"
15112
15113         rm -rf $DIR/$tdir
15114         changelog_deregister
15115 }
15116 run_test 160k "Verify that changelog records are not lost"
15117
15118 # Verifies that a file passed as a parameter has recently had an operation
15119 # performed on it that has generated an MTIME changelog which contains the
15120 # correct parent FID. As files might reside on a different MDT from the
15121 # parent directory in DNE configurations, the FIDs are translated to paths
15122 # before being compared, which should be identical
15123 compare_mtime_changelog() {
15124         local file="${1}"
15125         local mdtidx
15126         local mtime
15127         local cl_fid
15128         local pdir
15129         local dir
15130
15131         mdtidx=$($LFS getstripe --mdt-index $file)
15132         mdtidx=$(printf "%04x" $mdtidx)
15133
15134         # Obtain the parent FID from the MTIME changelog
15135         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15136         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15137
15138         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15139         [ -z "$cl_fid" ] && error "parent FID not present"
15140
15141         # Verify that the path for the parent FID is the same as the path for
15142         # the test directory
15143         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15144
15145         dir=$(dirname $1)
15146
15147         [[ "${pdir%/}" == "$dir" ]] ||
15148                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15149 }
15150
15151 test_160l() {
15152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15153
15154         remote_mds_nodsh && skip "remote MDS with nodsh"
15155         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15156                 skip "Need MDS version at least 2.13.55"
15157
15158         local cl_user
15159
15160         changelog_register || error "changelog_register failed"
15161         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15162
15163         changelog_users $SINGLEMDS | grep -q $cl_user ||
15164                 error "User '$cl_user' not found in changelog_users"
15165
15166         # Clear some types so that MTIME changelogs are generated
15167         changelog_chmask "-CREAT"
15168         changelog_chmask "-CLOSE"
15169
15170         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15171
15172         # Test CL_MTIME during setattr
15173         touch $DIR/$tdir/$tfile
15174         compare_mtime_changelog $DIR/$tdir/$tfile
15175
15176         # Test CL_MTIME during close
15177         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15178         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15179 }
15180 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15181
15182 test_161a() {
15183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15184
15185         test_mkdir -c1 $DIR/$tdir
15186         cp /etc/hosts $DIR/$tdir/$tfile
15187         test_mkdir -c1 $DIR/$tdir/foo1
15188         test_mkdir -c1 $DIR/$tdir/foo2
15189         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15190         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15191         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15192         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15193         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15194         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15195                 $LFS fid2path $DIR $FID
15196                 error "bad link ea"
15197         fi
15198         # middle
15199         rm $DIR/$tdir/foo2/zachary
15200         # last
15201         rm $DIR/$tdir/foo2/thor
15202         # first
15203         rm $DIR/$tdir/$tfile
15204         # rename
15205         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15206         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15207                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15208         rm $DIR/$tdir/foo2/maggie
15209
15210         # overflow the EA
15211         local longname=$tfile.avg_len_is_thirty_two_
15212         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15213                 error_noexit 'failed to unlink many hardlinks'" EXIT
15214         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15215                 error "failed to hardlink many files"
15216         links=$($LFS fid2path $DIR $FID | wc -l)
15217         echo -n "${links}/1000 links in link EA"
15218         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15219 }
15220 run_test 161a "link ea sanity"
15221
15222 test_161b() {
15223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15224         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15225
15226         local MDTIDX=1
15227         local remote_dir=$DIR/$tdir/remote_dir
15228
15229         mkdir -p $DIR/$tdir
15230         $LFS mkdir -i $MDTIDX $remote_dir ||
15231                 error "create remote directory failed"
15232
15233         cp /etc/hosts $remote_dir/$tfile
15234         mkdir -p $remote_dir/foo1
15235         mkdir -p $remote_dir/foo2
15236         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15237         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15238         ln $remote_dir/$tfile $remote_dir/foo1/luna
15239         ln $remote_dir/$tfile $remote_dir/foo2/thor
15240
15241         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15242                      tr -d ']')
15243         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15244                 $LFS fid2path $DIR $FID
15245                 error "bad link ea"
15246         fi
15247         # middle
15248         rm $remote_dir/foo2/zachary
15249         # last
15250         rm $remote_dir/foo2/thor
15251         # first
15252         rm $remote_dir/$tfile
15253         # rename
15254         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15255         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15256         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15257                 $LFS fid2path $DIR $FID
15258                 error "bad link rename"
15259         fi
15260         rm $remote_dir/foo2/maggie
15261
15262         # overflow the EA
15263         local longname=filename_avg_len_is_thirty_two_
15264         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15265                 error "failed to hardlink many files"
15266         links=$($LFS fid2path $DIR $FID | wc -l)
15267         echo -n "${links}/1000 links in link EA"
15268         [[ ${links} -gt 60 ]] ||
15269                 error "expected at least 60 links in link EA"
15270         unlinkmany $remote_dir/foo2/$longname 1000 ||
15271         error "failed to unlink many hardlinks"
15272 }
15273 run_test 161b "link ea sanity under remote directory"
15274
15275 test_161c() {
15276         remote_mds_nodsh && skip "remote MDS with nodsh"
15277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15278         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15279                 skip "Need MDS version at least 2.1.5"
15280
15281         # define CLF_RENAME_LAST 0x0001
15282         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15283         changelog_register || error "changelog_register failed"
15284
15285         rm -rf $DIR/$tdir
15286         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15287         touch $DIR/$tdir/foo_161c
15288         touch $DIR/$tdir/bar_161c
15289         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15290         changelog_dump | grep RENME | tail -n 5
15291         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15292         changelog_clear 0 || error "changelog_clear failed"
15293         if [ x$flags != "x0x1" ]; then
15294                 error "flag $flags is not 0x1"
15295         fi
15296
15297         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15298         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15299         touch $DIR/$tdir/foo_161c
15300         touch $DIR/$tdir/bar_161c
15301         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15302         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15303         changelog_dump | grep RENME | tail -n 5
15304         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15305         changelog_clear 0 || error "changelog_clear failed"
15306         if [ x$flags != "x0x0" ]; then
15307                 error "flag $flags is not 0x0"
15308         fi
15309         echo "rename overwrite a target having nlink > 1," \
15310                 "changelog record has flags of $flags"
15311
15312         # rename doesn't overwrite a target (changelog flag 0x0)
15313         touch $DIR/$tdir/foo_161c
15314         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15315         changelog_dump | grep RENME | tail -n 5
15316         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15317         changelog_clear 0 || error "changelog_clear failed"
15318         if [ x$flags != "x0x0" ]; then
15319                 error "flag $flags is not 0x0"
15320         fi
15321         echo "rename doesn't overwrite a target," \
15322                 "changelog record has flags of $flags"
15323
15324         # define CLF_UNLINK_LAST 0x0001
15325         # unlink a file having nlink = 1 (changelog flag 0x1)
15326         rm -f $DIR/$tdir/foo2_161c
15327         changelog_dump | grep UNLNK | tail -n 5
15328         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15329         changelog_clear 0 || error "changelog_clear failed"
15330         if [ x$flags != "x0x1" ]; then
15331                 error "flag $flags is not 0x1"
15332         fi
15333         echo "unlink a file having nlink = 1," \
15334                 "changelog record has flags of $flags"
15335
15336         # unlink a file having nlink > 1 (changelog flag 0x0)
15337         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15338         rm -f $DIR/$tdir/foobar_161c
15339         changelog_dump | grep UNLNK | tail -n 5
15340         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15341         changelog_clear 0 || error "changelog_clear failed"
15342         if [ x$flags != "x0x0" ]; then
15343                 error "flag $flags is not 0x0"
15344         fi
15345         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15346 }
15347 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15348
15349 test_161d() {
15350         remote_mds_nodsh && skip "remote MDS with nodsh"
15351         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15352
15353         local pid
15354         local fid
15355
15356         changelog_register || error "changelog_register failed"
15357
15358         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15359         # interfer with $MOUNT/.lustre/fid/ access
15360         mkdir $DIR/$tdir
15361         [[ $? -eq 0 ]] || error "mkdir failed"
15362
15363         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15364         $LCTL set_param fail_loc=0x8000140c
15365         # 5s pause
15366         $LCTL set_param fail_val=5
15367
15368         # create file
15369         echo foofoo > $DIR/$tdir/$tfile &
15370         pid=$!
15371
15372         # wait for create to be delayed
15373         sleep 2
15374
15375         ps -p $pid
15376         [[ $? -eq 0 ]] || error "create should be blocked"
15377
15378         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15379         stack_trap "rm -f $tempfile"
15380         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15381         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15382         # some delay may occur during ChangeLog publishing and file read just
15383         # above, that could allow file write to happen finally
15384         [[ -s $tempfile ]] && echo "file should be empty"
15385
15386         $LCTL set_param fail_loc=0
15387
15388         wait $pid
15389         [[ $? -eq 0 ]] || error "create failed"
15390 }
15391 run_test 161d "create with concurrent .lustre/fid access"
15392
15393 check_path() {
15394         local expected="$1"
15395         shift
15396         local fid="$2"
15397
15398         local path
15399         path=$($LFS fid2path "$@")
15400         local rc=$?
15401
15402         if [ $rc -ne 0 ]; then
15403                 error "path looked up of '$expected' failed: rc=$rc"
15404         elif [ "$path" != "$expected" ]; then
15405                 error "path looked up '$path' instead of '$expected'"
15406         else
15407                 echo "FID '$fid' resolves to path '$path' as expected"
15408         fi
15409 }
15410
15411 test_162a() { # was test_162
15412         test_mkdir -p -c1 $DIR/$tdir/d2
15413         touch $DIR/$tdir/d2/$tfile
15414         touch $DIR/$tdir/d2/x1
15415         touch $DIR/$tdir/d2/x2
15416         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15417         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15418         # regular file
15419         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15420         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15421
15422         # softlink
15423         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15424         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15425         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15426
15427         # softlink to wrong file
15428         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15429         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15430         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15431
15432         # hardlink
15433         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15434         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15435         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15436         # fid2path dir/fsname should both work
15437         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15438         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15439
15440         # hardlink count: check that there are 2 links
15441         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15442         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15443
15444         # hardlink indexing: remove the first link
15445         rm $DIR/$tdir/d2/p/q/r/hlink
15446         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15447 }
15448 run_test 162a "path lookup sanity"
15449
15450 test_162b() {
15451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15452         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15453
15454         mkdir $DIR/$tdir
15455         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15456                                 error "create striped dir failed"
15457
15458         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15459                                         tail -n 1 | awk '{print $2}')
15460         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15461
15462         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15463         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15464
15465         # regular file
15466         for ((i=0;i<5;i++)); do
15467                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15468                         error "get fid for f$i failed"
15469                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15470
15471                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15472                         error "get fid for d$i failed"
15473                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15474         done
15475
15476         return 0
15477 }
15478 run_test 162b "striped directory path lookup sanity"
15479
15480 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15481 test_162c() {
15482         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15483                 skip "Need MDS version at least 2.7.51"
15484
15485         local lpath=$tdir.local
15486         local rpath=$tdir.remote
15487
15488         test_mkdir $DIR/$lpath
15489         test_mkdir $DIR/$rpath
15490
15491         for ((i = 0; i <= 101; i++)); do
15492                 lpath="$lpath/$i"
15493                 mkdir $DIR/$lpath
15494                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15495                         error "get fid for local directory $DIR/$lpath failed"
15496                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15497
15498                 rpath="$rpath/$i"
15499                 test_mkdir $DIR/$rpath
15500                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15501                         error "get fid for remote directory $DIR/$rpath failed"
15502                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15503         done
15504
15505         return 0
15506 }
15507 run_test 162c "fid2path works with paths 100 or more directories deep"
15508
15509 oalr_event_count() {
15510         local event="${1}"
15511         local trace="${2}"
15512
15513         awk -v name="${FSNAME}-OST0000" \
15514             -v event="${event}" \
15515             '$1 == "TRACE" && $2 == event && $3 == name' \
15516             "${trace}" |
15517         wc -l
15518 }
15519
15520 oalr_expect_event_count() {
15521         local event="${1}"
15522         local trace="${2}"
15523         local expect="${3}"
15524         local count
15525
15526         count=$(oalr_event_count "${event}" "${trace}")
15527         if ((count == expect)); then
15528                 return 0
15529         fi
15530
15531         error_noexit "${event} event count was '${count}', expected ${expect}"
15532         cat "${trace}" >&2
15533         exit 1
15534 }
15535
15536 cleanup_165() {
15537         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15538         stop ost1
15539         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15540 }
15541
15542 setup_165() {
15543         sync # Flush previous IOs so we can count log entries.
15544         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15545         stack_trap cleanup_165 EXIT
15546 }
15547
15548 test_165a() {
15549         local trace="/tmp/${tfile}.trace"
15550         local rc
15551         local count
15552
15553         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15554                 skip "OFD access log unsupported"
15555
15556         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15557         setup_165
15558         sleep 5
15559
15560         do_facet ost1 ofd_access_log_reader --list
15561         stop ost1
15562
15563         do_facet ost1 killall -TERM ofd_access_log_reader
15564         wait
15565         rc=$?
15566
15567         if ((rc != 0)); then
15568                 error "ofd_access_log_reader exited with rc = '${rc}'"
15569         fi
15570
15571         # Parse trace file for discovery events:
15572         oalr_expect_event_count alr_log_add "${trace}" 1
15573         oalr_expect_event_count alr_log_eof "${trace}" 1
15574         oalr_expect_event_count alr_log_free "${trace}" 1
15575 }
15576 run_test 165a "ofd access log discovery"
15577
15578 test_165b() {
15579         local trace="/tmp/${tfile}.trace"
15580         local file="${DIR}/${tfile}"
15581         local pfid1
15582         local pfid2
15583         local -a entry
15584         local rc
15585         local count
15586         local size
15587         local flags
15588
15589         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15590                 skip "OFD access log unsupported"
15591
15592         setup_165
15593
15594         lfs setstripe -c 1 -i 0 "${file}"
15595         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15596                 error "cannot create '${file}'"
15597         do_facet ost1 ofd_access_log_reader --list
15598
15599         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15600         sleep 5
15601         do_facet ost1 killall -TERM ofd_access_log_reader
15602         wait
15603         rc=$?
15604
15605         if ((rc != 0)); then
15606                 error "ofd_access_log_reader exited with rc = '${rc}'"
15607         fi
15608
15609         oalr_expect_event_count alr_log_entry "${trace}" 1
15610
15611         pfid1=$($LFS path2fid "${file}")
15612
15613         # 1     2             3   4    5     6   7    8    9     10
15614         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15615         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15616
15617         echo "entry = '${entry[*]}'" >&2
15618
15619         pfid2=${entry[4]}
15620         if [[ "${pfid1}" != "${pfid2}" ]]; then
15621                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15622         fi
15623
15624         size=${entry[8]}
15625         if ((size != 1048576)); then
15626                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15627         fi
15628
15629         flags=${entry[10]}
15630         if [[ "${flags}" != "w" ]]; then
15631                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15632         fi
15633
15634         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15635         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15636                 error "cannot read '${file}'"
15637         sleep 5
15638         do_facet ost1 killall -TERM ofd_access_log_reader
15639         wait
15640         rc=$?
15641
15642         if ((rc != 0)); then
15643                 error "ofd_access_log_reader exited with rc = '${rc}'"
15644         fi
15645
15646         oalr_expect_event_count alr_log_entry "${trace}" 1
15647
15648         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15649         echo "entry = '${entry[*]}'" >&2
15650
15651         pfid2=${entry[4]}
15652         if [[ "${pfid1}" != "${pfid2}" ]]; then
15653                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15654         fi
15655
15656         size=${entry[8]}
15657         if ((size != 524288)); then
15658                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15659         fi
15660
15661         flags=${entry[10]}
15662         if [[ "${flags}" != "r" ]]; then
15663                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15664         fi
15665 }
15666 run_test 165b "ofd access log entries are produced and consumed"
15667
15668 test_165c() {
15669         local file="${DIR}/${tdir}/${tfile}"
15670
15671         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15672                 skip "OFD access log unsupported"
15673
15674         test_mkdir "${DIR}/${tdir}"
15675
15676         setup_165
15677
15678         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15679
15680         # 4096 / 64 = 64. Create twice as many entries.
15681         for ((i = 0; i < 128; i++)); do
15682                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
15683                         error "cannot create file"
15684         done
15685
15686         sync
15687         do_facet ost1 ofd_access_log_reader --list
15688         unlinkmany  "${file}-%d" 128
15689 }
15690 run_test 165c "full ofd access logs do not block IOs"
15691
15692 oal_peek_entry_count() {
15693         do_facet ost1 ofd_access_log_reader --list |
15694                 awk '$1 == "_entry_count:" { print $2; }'
15695 }
15696
15697 oal_expect_entry_count() {
15698         local entry_count=$(oal_peek_entry_count)
15699         local expect="$1"
15700
15701         if ((entry_count == expect)); then
15702                 return 0
15703         fi
15704
15705         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15706         do_facet ost1 ofd_access_log_reader --list >&2
15707         exit 1
15708 }
15709
15710 test_165d() {
15711         local trace="/tmp/${tfile}.trace"
15712         local file="${DIR}/${tdir}/${tfile}"
15713         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15714         local entry_count
15715
15716         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15717                 skip "OFD access log unsupported"
15718
15719         test_mkdir "${DIR}/${tdir}"
15720
15721         setup_165
15722         lfs setstripe -c 1 -i 0 "${file}"
15723
15724         do_facet ost1 lctl set_param "${param}=rw"
15725         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15726                 error "cannot create '${file}'"
15727         oal_expect_entry_count 1
15728
15729         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15730                 error "cannot read '${file}'"
15731         oal_expect_entry_count 2
15732
15733         do_facet ost1 lctl set_param "${param}=r"
15734         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15735                 error "cannot create '${file}'"
15736         oal_expect_entry_count 2
15737
15738         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15739                 error "cannot read '${file}'"
15740         oal_expect_entry_count 3
15741
15742         do_facet ost1 lctl set_param "${param}=w"
15743         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15744                 error "cannot create '${file}'"
15745         oal_expect_entry_count 4
15746
15747         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15748                 error "cannot read '${file}'"
15749         oal_expect_entry_count 4
15750
15751         do_facet ost1 lctl set_param "${param}=0"
15752         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15753                 error "cannot create '${file}'"
15754         oal_expect_entry_count 4
15755
15756         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15757                 error "cannot read '${file}'"
15758         oal_expect_entry_count 4
15759 }
15760 run_test 165d "ofd_access_log mask works"
15761
15762 test_169() {
15763         # do directio so as not to populate the page cache
15764         log "creating a 10 Mb file"
15765         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
15766                 error "multiop failed while creating a file"
15767         log "starting reads"
15768         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15769         log "truncating the file"
15770         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
15771                 error "multiop failed while truncating the file"
15772         log "killing dd"
15773         kill %+ || true # reads might have finished
15774         echo "wait until dd is finished"
15775         wait
15776         log "removing the temporary file"
15777         rm -rf $DIR/$tfile || error "tmp file removal failed"
15778 }
15779 run_test 169 "parallel read and truncate should not deadlock"
15780
15781 test_170() {
15782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15783
15784         $LCTL clear     # bug 18514
15785         $LCTL debug_daemon start $TMP/${tfile}_log_good
15786         touch $DIR/$tfile
15787         $LCTL debug_daemon stop
15788         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15789                 error "sed failed to read log_good"
15790
15791         $LCTL debug_daemon start $TMP/${tfile}_log_good
15792         rm -rf $DIR/$tfile
15793         $LCTL debug_daemon stop
15794
15795         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15796                error "lctl df log_bad failed"
15797
15798         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15799         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15800
15801         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15802         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15803
15804         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15805                 error "bad_line good_line1 good_line2 are empty"
15806
15807         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15808         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15809         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15810
15811         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15812         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15813         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15814
15815         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15816                 error "bad_line_new good_line_new are empty"
15817
15818         local expected_good=$((good_line1 + good_line2*2))
15819
15820         rm -f $TMP/${tfile}*
15821         # LU-231, short malformed line may not be counted into bad lines
15822         if [ $bad_line -ne $bad_line_new ] &&
15823                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15824                 error "expected $bad_line bad lines, but got $bad_line_new"
15825                 return 1
15826         fi
15827
15828         if [ $expected_good -ne $good_line_new ]; then
15829                 error "expected $expected_good good lines, but got $good_line_new"
15830                 return 2
15831         fi
15832         true
15833 }
15834 run_test 170 "test lctl df to handle corrupted log ====================="
15835
15836 test_171() { # bug20592
15837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15838
15839         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15840         $LCTL set_param fail_loc=0x50e
15841         $LCTL set_param fail_val=3000
15842         multiop_bg_pause $DIR/$tfile O_s || true
15843         local MULTIPID=$!
15844         kill -USR1 $MULTIPID
15845         # cause log dump
15846         sleep 3
15847         wait $MULTIPID
15848         if dmesg | grep "recursive fault"; then
15849                 error "caught a recursive fault"
15850         fi
15851         $LCTL set_param fail_loc=0
15852         true
15853 }
15854 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15855
15856 # it would be good to share it with obdfilter-survey/iokit-libecho code
15857 setup_obdecho_osc () {
15858         local rc=0
15859         local ost_nid=$1
15860         local obdfilter_name=$2
15861         echo "Creating new osc for $obdfilter_name on $ost_nid"
15862         # make sure we can find loopback nid
15863         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15864
15865         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15866                            ${obdfilter_name}_osc_UUID || rc=2; }
15867         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15868                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15869         return $rc
15870 }
15871
15872 cleanup_obdecho_osc () {
15873         local obdfilter_name=$1
15874         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15875         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15876         return 0
15877 }
15878
15879 obdecho_test() {
15880         local OBD=$1
15881         local node=$2
15882         local pages=${3:-64}
15883         local rc=0
15884         local id
15885
15886         local count=10
15887         local obd_size=$(get_obd_size $node $OBD)
15888         local page_size=$(get_page_size $node)
15889         if [[ -n "$obd_size" ]]; then
15890                 local new_count=$((obd_size / (pages * page_size / 1024)))
15891                 [[ $new_count -ge $count ]] || count=$new_count
15892         fi
15893
15894         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15895         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15896                            rc=2; }
15897         if [ $rc -eq 0 ]; then
15898             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15899             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15900         fi
15901         echo "New object id is $id"
15902         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15903                            rc=4; }
15904         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15905                            "test_brw $count w v $pages $id" || rc=4; }
15906         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15907                            rc=4; }
15908         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15909                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15910         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15911                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15912         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15913         return $rc
15914 }
15915
15916 test_180a() {
15917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15918
15919         if ! [ -d /sys/fs/lustre/echo_client ] &&
15920            ! module_loaded obdecho; then
15921                 load_module obdecho/obdecho &&
15922                         stack_trap "rmmod obdecho" EXIT ||
15923                         error "unable to load obdecho on client"
15924         fi
15925
15926         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15927         local host=$($LCTL get_param -n osc.$osc.import |
15928                      awk '/current_connection:/ { print $2 }' )
15929         local target=$($LCTL get_param -n osc.$osc.import |
15930                        awk '/target:/ { print $2 }' )
15931         target=${target%_UUID}
15932
15933         if [ -n "$target" ]; then
15934                 setup_obdecho_osc $host $target &&
15935                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15936                         { error "obdecho setup failed with $?"; return; }
15937
15938                 obdecho_test ${target}_osc client ||
15939                         error "obdecho_test failed on ${target}_osc"
15940         else
15941                 $LCTL get_param osc.$osc.import
15942                 error "there is no osc.$osc.import target"
15943         fi
15944 }
15945 run_test 180a "test obdecho on osc"
15946
15947 test_180b() {
15948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15949         remote_ost_nodsh && skip "remote OST with nodsh"
15950
15951         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15952                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15953                 error "failed to load module obdecho"
15954
15955         local target=$(do_facet ost1 $LCTL dl |
15956                        awk '/obdfilter/ { print $4; exit; }')
15957
15958         if [ -n "$target" ]; then
15959                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15960         else
15961                 do_facet ost1 $LCTL dl
15962                 error "there is no obdfilter target on ost1"
15963         fi
15964 }
15965 run_test 180b "test obdecho directly on obdfilter"
15966
15967 test_180c() { # LU-2598
15968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15969         remote_ost_nodsh && skip "remote OST with nodsh"
15970         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15971                 skip "Need MDS version at least 2.4.0"
15972
15973         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15974                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15975                 error "failed to load module obdecho"
15976
15977         local target=$(do_facet ost1 $LCTL dl |
15978                        awk '/obdfilter/ { print $4; exit; }')
15979
15980         if [ -n "$target" ]; then
15981                 local pages=16384 # 64MB bulk I/O RPC size
15982
15983                 obdecho_test "$target" ost1 "$pages" ||
15984                         error "obdecho_test with pages=$pages failed with $?"
15985         else
15986                 do_facet ost1 $LCTL dl
15987                 error "there is no obdfilter target on ost1"
15988         fi
15989 }
15990 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15991
15992 test_181() { # bug 22177
15993         test_mkdir $DIR/$tdir
15994         # create enough files to index the directory
15995         createmany -o $DIR/$tdir/foobar 4000
15996         # print attributes for debug purpose
15997         lsattr -d .
15998         # open dir
15999         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16000         MULTIPID=$!
16001         # remove the files & current working dir
16002         unlinkmany $DIR/$tdir/foobar 4000
16003         rmdir $DIR/$tdir
16004         kill -USR1 $MULTIPID
16005         wait $MULTIPID
16006         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16007         return 0
16008 }
16009 run_test 181 "Test open-unlinked dir ========================"
16010
16011 test_182() {
16012         local fcount=1000
16013         local tcount=10
16014
16015         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16016
16017         $LCTL set_param mdc.*.rpc_stats=clear
16018
16019         for (( i = 0; i < $tcount; i++ )) ; do
16020                 mkdir $DIR/$tdir/$i
16021         done
16022
16023         for (( i = 0; i < $tcount; i++ )) ; do
16024                 createmany -o $DIR/$tdir/$i/f- $fcount &
16025         done
16026         wait
16027
16028         for (( i = 0; i < $tcount; i++ )) ; do
16029                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16030         done
16031         wait
16032
16033         $LCTL get_param mdc.*.rpc_stats
16034
16035         rm -rf $DIR/$tdir
16036 }
16037 run_test 182 "Test parallel modify metadata operations ================"
16038
16039 test_183() { # LU-2275
16040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16041         remote_mds_nodsh && skip "remote MDS with nodsh"
16042         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16043                 skip "Need MDS version at least 2.3.56"
16044
16045         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16046         echo aaa > $DIR/$tdir/$tfile
16047
16048 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16049         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16050
16051         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16052         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16053
16054         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16055
16056         # Flush negative dentry cache
16057         touch $DIR/$tdir/$tfile
16058
16059         # We are not checking for any leaked references here, they'll
16060         # become evident next time we do cleanup with module unload.
16061         rm -rf $DIR/$tdir
16062 }
16063 run_test 183 "No crash or request leak in case of strange dispositions ========"
16064
16065 # test suite 184 is for LU-2016, LU-2017
16066 test_184a() {
16067         check_swap_layouts_support
16068
16069         dir0=$DIR/$tdir/$testnum
16070         test_mkdir -p -c1 $dir0
16071         ref1=/etc/passwd
16072         ref2=/etc/group
16073         file1=$dir0/f1
16074         file2=$dir0/f2
16075         $LFS setstripe -c1 $file1
16076         cp $ref1 $file1
16077         $LFS setstripe -c2 $file2
16078         cp $ref2 $file2
16079         gen1=$($LFS getstripe -g $file1)
16080         gen2=$($LFS getstripe -g $file2)
16081
16082         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16083         gen=$($LFS getstripe -g $file1)
16084         [[ $gen1 != $gen ]] ||
16085                 "Layout generation on $file1 does not change"
16086         gen=$($LFS getstripe -g $file2)
16087         [[ $gen2 != $gen ]] ||
16088                 "Layout generation on $file2 does not change"
16089
16090         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16091         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16092
16093         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16094 }
16095 run_test 184a "Basic layout swap"
16096
16097 test_184b() {
16098         check_swap_layouts_support
16099
16100         dir0=$DIR/$tdir/$testnum
16101         mkdir -p $dir0 || error "creating dir $dir0"
16102         file1=$dir0/f1
16103         file2=$dir0/f2
16104         file3=$dir0/f3
16105         dir1=$dir0/d1
16106         dir2=$dir0/d2
16107         mkdir $dir1 $dir2
16108         $LFS setstripe -c1 $file1
16109         $LFS setstripe -c2 $file2
16110         $LFS setstripe -c1 $file3
16111         chown $RUNAS_ID $file3
16112         gen1=$($LFS getstripe -g $file1)
16113         gen2=$($LFS getstripe -g $file2)
16114
16115         $LFS swap_layouts $dir1 $dir2 &&
16116                 error "swap of directories layouts should fail"
16117         $LFS swap_layouts $dir1 $file1 &&
16118                 error "swap of directory and file layouts should fail"
16119         $RUNAS $LFS swap_layouts $file1 $file2 &&
16120                 error "swap of file we cannot write should fail"
16121         $LFS swap_layouts $file1 $file3 &&
16122                 error "swap of file with different owner should fail"
16123         /bin/true # to clear error code
16124 }
16125 run_test 184b "Forbidden layout swap (will generate errors)"
16126
16127 test_184c() {
16128         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16129         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16130         check_swap_layouts_support
16131         check_swap_layout_no_dom $DIR
16132
16133         local dir0=$DIR/$tdir/$testnum
16134         mkdir -p $dir0 || error "creating dir $dir0"
16135
16136         local ref1=$dir0/ref1
16137         local ref2=$dir0/ref2
16138         local file1=$dir0/file1
16139         local file2=$dir0/file2
16140         # create a file large enough for the concurrent test
16141         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16142         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16143         echo "ref file size: ref1($(stat -c %s $ref1))," \
16144              "ref2($(stat -c %s $ref2))"
16145
16146         cp $ref2 $file2
16147         dd if=$ref1 of=$file1 bs=16k &
16148         local DD_PID=$!
16149
16150         # Make sure dd starts to copy file, but wait at most 5 seconds
16151         local loops=0
16152         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16153
16154         $LFS swap_layouts $file1 $file2
16155         local rc=$?
16156         wait $DD_PID
16157         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16158         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16159
16160         # how many bytes copied before swapping layout
16161         local copied=$(stat -c %s $file2)
16162         local remaining=$(stat -c %s $ref1)
16163         remaining=$((remaining - copied))
16164         echo "Copied $copied bytes before swapping layout..."
16165
16166         cmp -n $copied $file1 $ref2 | grep differ &&
16167                 error "Content mismatch [0, $copied) of ref2 and file1"
16168         cmp -n $copied $file2 $ref1 ||
16169                 error "Content mismatch [0, $copied) of ref1 and file2"
16170         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16171                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16172
16173         # clean up
16174         rm -f $ref1 $ref2 $file1 $file2
16175 }
16176 run_test 184c "Concurrent write and layout swap"
16177
16178 test_184d() {
16179         check_swap_layouts_support
16180         check_swap_layout_no_dom $DIR
16181         [ -z "$(which getfattr 2>/dev/null)" ] &&
16182                 skip_env "no getfattr command"
16183
16184         local file1=$DIR/$tdir/$tfile-1
16185         local file2=$DIR/$tdir/$tfile-2
16186         local file3=$DIR/$tdir/$tfile-3
16187         local lovea1
16188         local lovea2
16189
16190         mkdir -p $DIR/$tdir
16191         touch $file1 || error "create $file1 failed"
16192         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16193                 error "create $file2 failed"
16194         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16195                 error "create $file3 failed"
16196         lovea1=$(get_layout_param $file1)
16197
16198         $LFS swap_layouts $file2 $file3 ||
16199                 error "swap $file2 $file3 layouts failed"
16200         $LFS swap_layouts $file1 $file2 ||
16201                 error "swap $file1 $file2 layouts failed"
16202
16203         lovea2=$(get_layout_param $file2)
16204         echo "$lovea1"
16205         echo "$lovea2"
16206         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16207
16208         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16209         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16210 }
16211 run_test 184d "allow stripeless layouts swap"
16212
16213 test_184e() {
16214         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16215                 skip "Need MDS version at least 2.6.94"
16216         check_swap_layouts_support
16217         check_swap_layout_no_dom $DIR
16218         [ -z "$(which getfattr 2>/dev/null)" ] &&
16219                 skip_env "no getfattr command"
16220
16221         local file1=$DIR/$tdir/$tfile-1
16222         local file2=$DIR/$tdir/$tfile-2
16223         local file3=$DIR/$tdir/$tfile-3
16224         local lovea
16225
16226         mkdir -p $DIR/$tdir
16227         touch $file1 || error "create $file1 failed"
16228         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16229                 error "create $file2 failed"
16230         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16231                 error "create $file3 failed"
16232
16233         $LFS swap_layouts $file1 $file2 ||
16234                 error "swap $file1 $file2 layouts failed"
16235
16236         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16237         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16238
16239         echo 123 > $file1 || error "Should be able to write into $file1"
16240
16241         $LFS swap_layouts $file1 $file3 ||
16242                 error "swap $file1 $file3 layouts failed"
16243
16244         echo 123 > $file1 || error "Should be able to write into $file1"
16245
16246         rm -rf $file1 $file2 $file3
16247 }
16248 run_test 184e "Recreate layout after stripeless layout swaps"
16249
16250 test_184f() {
16251         # Create a file with name longer than sizeof(struct stat) ==
16252         # 144 to see if we can get chars from the file name to appear
16253         # in the returned striping. Note that 'f' == 0x66.
16254         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16255
16256         mkdir -p $DIR/$tdir
16257         mcreate $DIR/$tdir/$file
16258         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16259                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16260         fi
16261 }
16262 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16263
16264 test_185() { # LU-2441
16265         # LU-3553 - no volatile file support in old servers
16266         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16267                 skip "Need MDS version at least 2.3.60"
16268
16269         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16270         touch $DIR/$tdir/spoo
16271         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16272         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16273                 error "cannot create/write a volatile file"
16274         [ "$FILESET" == "" ] &&
16275         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16276                 error "FID is still valid after close"
16277
16278         multiop_bg_pause $DIR/$tdir vVw4096_c
16279         local multi_pid=$!
16280
16281         local OLD_IFS=$IFS
16282         IFS=":"
16283         local fidv=($fid)
16284         IFS=$OLD_IFS
16285         # assume that the next FID for this client is sequential, since stdout
16286         # is unfortunately eaten by multiop_bg_pause
16287         local n=$((${fidv[1]} + 1))
16288         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16289         if [ "$FILESET" == "" ]; then
16290                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16291                         error "FID is missing before close"
16292         fi
16293         kill -USR1 $multi_pid
16294         # 1 second delay, so if mtime change we will see it
16295         sleep 1
16296         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16297         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16298 }
16299 run_test 185 "Volatile file support"
16300
16301 function create_check_volatile() {
16302         local idx=$1
16303         local tgt
16304
16305         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16306         local PID=$!
16307         sleep 1
16308         local FID=$(cat /tmp/${tfile}.fid)
16309         [ "$FID" == "" ] && error "can't get FID for volatile"
16310         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16311         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16312         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16313         kill -USR1 $PID
16314         wait
16315         sleep 1
16316         cancel_lru_locks mdc # flush opencache
16317         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16318         return 0
16319 }
16320
16321 test_185a(){
16322         # LU-12516 - volatile creation via .lustre
16323         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16324                 skip "Need MDS version at least 2.3.55"
16325
16326         create_check_volatile 0
16327         [ $MDSCOUNT -lt 2 ] && return 0
16328
16329         # DNE case
16330         create_check_volatile 1
16331
16332         return 0
16333 }
16334 run_test 185a "Volatile file creation in .lustre/fid/"
16335
16336 test_187a() {
16337         remote_mds_nodsh && skip "remote MDS with nodsh"
16338         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16339                 skip "Need MDS version at least 2.3.0"
16340
16341         local dir0=$DIR/$tdir/$testnum
16342         mkdir -p $dir0 || error "creating dir $dir0"
16343
16344         local file=$dir0/file1
16345         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16346         local dv1=$($LFS data_version $file)
16347         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16348         local dv2=$($LFS data_version $file)
16349         [[ $dv1 != $dv2 ]] ||
16350                 error "data version did not change on write $dv1 == $dv2"
16351
16352         # clean up
16353         rm -f $file1
16354 }
16355 run_test 187a "Test data version change"
16356
16357 test_187b() {
16358         remote_mds_nodsh && skip "remote MDS with nodsh"
16359         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16360                 skip "Need MDS version at least 2.3.0"
16361
16362         local dir0=$DIR/$tdir/$testnum
16363         mkdir -p $dir0 || error "creating dir $dir0"
16364
16365         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16366         [[ ${DV[0]} != ${DV[1]} ]] ||
16367                 error "data version did not change on write"\
16368                       " ${DV[0]} == ${DV[1]}"
16369
16370         # clean up
16371         rm -f $file1
16372 }
16373 run_test 187b "Test data version change on volatile file"
16374
16375 test_200() {
16376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16377         remote_mgs_nodsh && skip "remote MGS with nodsh"
16378         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16379
16380         local POOL=${POOL:-cea1}
16381         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16382         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16383         # Pool OST targets
16384         local first_ost=0
16385         local last_ost=$(($OSTCOUNT - 1))
16386         local ost_step=2
16387         local ost_list=$(seq $first_ost $ost_step $last_ost)
16388         local ost_range="$first_ost $last_ost $ost_step"
16389         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16390         local file_dir=$POOL_ROOT/file_tst
16391         local subdir=$test_path/subdir
16392         local rc=0
16393
16394         while : ; do
16395                 # former test_200a test_200b
16396                 pool_add $POOL                          || { rc=$? ; break; }
16397                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16398                 # former test_200c test_200d
16399                 mkdir -p $test_path
16400                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16401                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16402                 mkdir -p $subdir
16403                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16404                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16405                                                         || { rc=$? ; break; }
16406                 # former test_200e test_200f
16407                 local files=$((OSTCOUNT*3))
16408                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16409                                                         || { rc=$? ; break; }
16410                 pool_create_files $POOL $file_dir $files "$ost_list" \
16411                                                         || { rc=$? ; break; }
16412                 # former test_200g test_200h
16413                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16414                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16415
16416                 # former test_201a test_201b test_201c
16417                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16418
16419                 local f=$test_path/$tfile
16420                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16421                 pool_remove $POOL $f                    || { rc=$? ; break; }
16422                 break
16423         done
16424
16425         destroy_test_pools
16426
16427         return $rc
16428 }
16429 run_test 200 "OST pools"
16430
16431 # usage: default_attr <count | size | offset>
16432 default_attr() {
16433         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16434 }
16435
16436 # usage: check_default_stripe_attr
16437 check_default_stripe_attr() {
16438         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16439         case $1 in
16440         --stripe-count|-c)
16441                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16442         --stripe-size|-S)
16443                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16444         --stripe-index|-i)
16445                 EXPECTED=-1;;
16446         *)
16447                 error "unknown getstripe attr '$1'"
16448         esac
16449
16450         [ $ACTUAL == $EXPECTED ] ||
16451                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16452 }
16453
16454 test_204a() {
16455         test_mkdir $DIR/$tdir
16456         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16457
16458         check_default_stripe_attr --stripe-count
16459         check_default_stripe_attr --stripe-size
16460         check_default_stripe_attr --stripe-index
16461 }
16462 run_test 204a "Print default stripe attributes"
16463
16464 test_204b() {
16465         test_mkdir $DIR/$tdir
16466         $LFS setstripe --stripe-count 1 $DIR/$tdir
16467
16468         check_default_stripe_attr --stripe-size
16469         check_default_stripe_attr --stripe-index
16470 }
16471 run_test 204b "Print default stripe size and offset"
16472
16473 test_204c() {
16474         test_mkdir $DIR/$tdir
16475         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16476
16477         check_default_stripe_attr --stripe-count
16478         check_default_stripe_attr --stripe-index
16479 }
16480 run_test 204c "Print default stripe count and offset"
16481
16482 test_204d() {
16483         test_mkdir $DIR/$tdir
16484         $LFS setstripe --stripe-index 0 $DIR/$tdir
16485
16486         check_default_stripe_attr --stripe-count
16487         check_default_stripe_attr --stripe-size
16488 }
16489 run_test 204d "Print default stripe count and size"
16490
16491 test_204e() {
16492         test_mkdir $DIR/$tdir
16493         $LFS setstripe -d $DIR/$tdir
16494
16495         check_default_stripe_attr --stripe-count --raw
16496         check_default_stripe_attr --stripe-size --raw
16497         check_default_stripe_attr --stripe-index --raw
16498 }
16499 run_test 204e "Print raw stripe attributes"
16500
16501 test_204f() {
16502         test_mkdir $DIR/$tdir
16503         $LFS setstripe --stripe-count 1 $DIR/$tdir
16504
16505         check_default_stripe_attr --stripe-size --raw
16506         check_default_stripe_attr --stripe-index --raw
16507 }
16508 run_test 204f "Print raw stripe size and offset"
16509
16510 test_204g() {
16511         test_mkdir $DIR/$tdir
16512         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16513
16514         check_default_stripe_attr --stripe-count --raw
16515         check_default_stripe_attr --stripe-index --raw
16516 }
16517 run_test 204g "Print raw stripe count and offset"
16518
16519 test_204h() {
16520         test_mkdir $DIR/$tdir
16521         $LFS setstripe --stripe-index 0 $DIR/$tdir
16522
16523         check_default_stripe_attr --stripe-count --raw
16524         check_default_stripe_attr --stripe-size --raw
16525 }
16526 run_test 204h "Print raw stripe count and size"
16527
16528 # Figure out which job scheduler is being used, if any,
16529 # or use a fake one
16530 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16531         JOBENV=SLURM_JOB_ID
16532 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16533         JOBENV=LSB_JOBID
16534 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16535         JOBENV=PBS_JOBID
16536 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16537         JOBENV=LOADL_STEP_ID
16538 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16539         JOBENV=JOB_ID
16540 else
16541         $LCTL list_param jobid_name > /dev/null 2>&1
16542         if [ $? -eq 0 ]; then
16543                 JOBENV=nodelocal
16544         else
16545                 JOBENV=FAKE_JOBID
16546         fi
16547 fi
16548 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16549
16550 verify_jobstats() {
16551         local cmd=($1)
16552         shift
16553         local facets="$@"
16554
16555 # we don't really need to clear the stats for this test to work, since each
16556 # command has a unique jobid, but it makes debugging easier if needed.
16557 #       for facet in $facets; do
16558 #               local dev=$(convert_facet2label $facet)
16559 #               # clear old jobstats
16560 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16561 #       done
16562
16563         # use a new JobID for each test, or we might see an old one
16564         [ "$JOBENV" = "FAKE_JOBID" ] &&
16565                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16566
16567         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16568
16569         [ "$JOBENV" = "nodelocal" ] && {
16570                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16571                 $LCTL set_param jobid_name=$FAKE_JOBID
16572                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16573         }
16574
16575         log "Test: ${cmd[*]}"
16576         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16577
16578         if [ $JOBENV = "FAKE_JOBID" ]; then
16579                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16580         else
16581                 ${cmd[*]}
16582         fi
16583
16584         # all files are created on OST0000
16585         for facet in $facets; do
16586                 local stats="*.$(convert_facet2label $facet).job_stats"
16587
16588                 # strip out libtool wrappers for in-tree executables
16589                 if [ $(do_facet $facet lctl get_param $stats |
16590                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16591                         do_facet $facet lctl get_param $stats
16592                         error "No jobstats for $JOBVAL found on $facet::$stats"
16593                 fi
16594         done
16595 }
16596
16597 jobstats_set() {
16598         local new_jobenv=$1
16599
16600         set_persistent_param_and_check client "jobid_var" \
16601                 "$FSNAME.sys.jobid_var" $new_jobenv
16602 }
16603
16604 test_205a() { # Job stats
16605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16606         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16607                 skip "Need MDS version with at least 2.7.1"
16608         remote_mgs_nodsh && skip "remote MGS with nodsh"
16609         remote_mds_nodsh && skip "remote MDS with nodsh"
16610         remote_ost_nodsh && skip "remote OST with nodsh"
16611         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16612                 skip "Server doesn't support jobstats"
16613         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16614
16615         local old_jobenv=$($LCTL get_param -n jobid_var)
16616         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16617
16618         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16619                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16620         else
16621                 stack_trap "do_facet mgs $PERM_CMD \
16622                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16623         fi
16624         changelog_register
16625
16626         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16627                                 mdt.*.job_cleanup_interval | head -n 1)
16628         local new_interval=5
16629         do_facet $SINGLEMDS \
16630                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16631         stack_trap "do_facet $SINGLEMDS \
16632                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16633         local start=$SECONDS
16634
16635         local cmd
16636         # mkdir
16637         cmd="mkdir $DIR/$tdir"
16638         verify_jobstats "$cmd" "$SINGLEMDS"
16639         # rmdir
16640         cmd="rmdir $DIR/$tdir"
16641         verify_jobstats "$cmd" "$SINGLEMDS"
16642         # mkdir on secondary MDT
16643         if [ $MDSCOUNT -gt 1 ]; then
16644                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16645                 verify_jobstats "$cmd" "mds2"
16646         fi
16647         # mknod
16648         cmd="mknod $DIR/$tfile c 1 3"
16649         verify_jobstats "$cmd" "$SINGLEMDS"
16650         # unlink
16651         cmd="rm -f $DIR/$tfile"
16652         verify_jobstats "$cmd" "$SINGLEMDS"
16653         # create all files on OST0000 so verify_jobstats can find OST stats
16654         # open & close
16655         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16656         verify_jobstats "$cmd" "$SINGLEMDS"
16657         # setattr
16658         cmd="touch $DIR/$tfile"
16659         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16660         # write
16661         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16662         verify_jobstats "$cmd" "ost1"
16663         # read
16664         cancel_lru_locks osc
16665         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16666         verify_jobstats "$cmd" "ost1"
16667         # truncate
16668         cmd="$TRUNCATE $DIR/$tfile 0"
16669         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16670         # rename
16671         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16672         verify_jobstats "$cmd" "$SINGLEMDS"
16673         # jobstats expiry - sleep until old stats should be expired
16674         local left=$((new_interval + 5 - (SECONDS - start)))
16675         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16676                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16677                         "0" $left
16678         cmd="mkdir $DIR/$tdir.expire"
16679         verify_jobstats "$cmd" "$SINGLEMDS"
16680         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16681             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16682
16683         # Ensure that jobid are present in changelog (if supported by MDS)
16684         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16685                 changelog_dump | tail -10
16686                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16687                 [ $jobids -eq 9 ] ||
16688                         error "Wrong changelog jobid count $jobids != 9"
16689
16690                 # LU-5862
16691                 JOBENV="disable"
16692                 jobstats_set $JOBENV
16693                 touch $DIR/$tfile
16694                 changelog_dump | grep $tfile
16695                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16696                 [ $jobids -eq 0 ] ||
16697                         error "Unexpected jobids when jobid_var=$JOBENV"
16698         fi
16699
16700         # test '%j' access to environment variable - if supported
16701         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16702                 JOBENV="JOBCOMPLEX"
16703                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16704
16705                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16706         fi
16707
16708         # test '%j' access to per-session jobid - if supported
16709         if lctl list_param jobid_this_session > /dev/null 2>&1
16710         then
16711                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16712                 lctl set_param jobid_this_session=$USER
16713
16714                 JOBENV="JOBCOMPLEX"
16715                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16716
16717                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16718         fi
16719 }
16720 run_test 205a "Verify job stats"
16721
16722 # LU-13117, LU-13597
16723 test_205b() {
16724         job_stats="mdt.*.job_stats"
16725         $LCTL set_param $job_stats=clear
16726         # Setting jobid_var to USER might not be supported
16727         $LCTL set_param jobid_var=USER || true
16728         $LCTL set_param jobid_name="%e.%u"
16729         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16730         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16731                 grep "job_id:.*foolish" &&
16732                         error "Unexpected jobid found"
16733         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16734                 grep "open:.*min.*max.*sum" ||
16735                         error "wrong job_stats format found"
16736 }
16737 run_test 205b "Verify job stats jobid and output format"
16738
16739 # LU-13733
16740 test_205c() {
16741         $LCTL set_param llite.*.stats=0
16742         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16743         $LCTL get_param llite.*.stats
16744         $LCTL get_param llite.*.stats | grep \
16745                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16746                         error "wrong client stats format found"
16747 }
16748 run_test 205c "Verify client stats format"
16749
16750 # LU-1480, LU-1773 and LU-1657
16751 test_206() {
16752         mkdir -p $DIR/$tdir
16753         $LFS setstripe -c -1 $DIR/$tdir
16754 #define OBD_FAIL_LOV_INIT 0x1403
16755         $LCTL set_param fail_loc=0xa0001403
16756         $LCTL set_param fail_val=1
16757         touch $DIR/$tdir/$tfile || true
16758 }
16759 run_test 206 "fail lov_init_raid0() doesn't lbug"
16760
16761 test_207a() {
16762         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16763         local fsz=`stat -c %s $DIR/$tfile`
16764         cancel_lru_locks mdc
16765
16766         # do not return layout in getattr intent
16767 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16768         $LCTL set_param fail_loc=0x170
16769         local sz=`stat -c %s $DIR/$tfile`
16770
16771         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16772
16773         rm -rf $DIR/$tfile
16774 }
16775 run_test 207a "can refresh layout at glimpse"
16776
16777 test_207b() {
16778         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16779         local cksum=`md5sum $DIR/$tfile`
16780         local fsz=`stat -c %s $DIR/$tfile`
16781         cancel_lru_locks mdc
16782         cancel_lru_locks osc
16783
16784         # do not return layout in getattr intent
16785 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16786         $LCTL set_param fail_loc=0x171
16787
16788         # it will refresh layout after the file is opened but before read issues
16789         echo checksum is "$cksum"
16790         echo "$cksum" |md5sum -c --quiet || error "file differs"
16791
16792         rm -rf $DIR/$tfile
16793 }
16794 run_test 207b "can refresh layout at open"
16795
16796 test_208() {
16797         # FIXME: in this test suite, only RD lease is used. This is okay
16798         # for now as only exclusive open is supported. After generic lease
16799         # is done, this test suite should be revised. - Jinshan
16800
16801         remote_mds_nodsh && skip "remote MDS with nodsh"
16802         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16803                 skip "Need MDS version at least 2.4.52"
16804
16805         echo "==== test 1: verify get lease work"
16806         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16807
16808         echo "==== test 2: verify lease can be broken by upcoming open"
16809         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16810         local PID=$!
16811         sleep 1
16812
16813         $MULTIOP $DIR/$tfile oO_RDONLY:c
16814         kill -USR1 $PID && wait $PID || error "break lease error"
16815
16816         echo "==== test 3: verify lease can't be granted if an open already exists"
16817         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16818         local PID=$!
16819         sleep 1
16820
16821         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16822         kill -USR1 $PID && wait $PID || error "open file error"
16823
16824         echo "==== test 4: lease can sustain over recovery"
16825         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16826         PID=$!
16827         sleep 1
16828
16829         fail mds1
16830
16831         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16832
16833         echo "==== test 5: lease broken can't be regained by replay"
16834         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16835         PID=$!
16836         sleep 1
16837
16838         # open file to break lease and then recovery
16839         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16840         fail mds1
16841
16842         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16843
16844         rm -f $DIR/$tfile
16845 }
16846 run_test 208 "Exclusive open"
16847
16848 test_209() {
16849         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16850                 skip_env "must have disp_stripe"
16851
16852         touch $DIR/$tfile
16853         sync; sleep 5; sync;
16854
16855         echo 3 > /proc/sys/vm/drop_caches
16856         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16857                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16858         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16859
16860         # open/close 500 times
16861         for i in $(seq 500); do
16862                 cat $DIR/$tfile
16863         done
16864
16865         echo 3 > /proc/sys/vm/drop_caches
16866         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16867                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16868         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16869
16870         echo "before: $req_before, after: $req_after"
16871         [ $((req_after - req_before)) -ge 300 ] &&
16872                 error "open/close requests are not freed"
16873         return 0
16874 }
16875 run_test 209 "read-only open/close requests should be freed promptly"
16876
16877 test_210() {
16878         local pid
16879
16880         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16881         pid=$!
16882         sleep 1
16883
16884         $LFS getstripe $DIR/$tfile
16885         kill -USR1 $pid
16886         wait $pid || error "multiop failed"
16887
16888         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16889         pid=$!
16890         sleep 1
16891
16892         $LFS getstripe $DIR/$tfile
16893         kill -USR1 $pid
16894         wait $pid || error "multiop failed"
16895 }
16896 run_test 210 "lfs getstripe does not break leases"
16897
16898 test_212() {
16899         size=`date +%s`
16900         size=$((size % 8192 + 1))
16901         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16902         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16903         rm -f $DIR/f212 $DIR/f212.xyz
16904 }
16905 run_test 212 "Sendfile test ============================================"
16906
16907 test_213() {
16908         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16909         cancel_lru_locks osc
16910         lctl set_param fail_loc=0x8000040f
16911         # generate a read lock
16912         cat $DIR/$tfile > /dev/null
16913         # write to the file, it will try to cancel the above read lock.
16914         cat /etc/hosts >> $DIR/$tfile
16915 }
16916 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16917
16918 test_214() { # for bug 20133
16919         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16920         for (( i=0; i < 340; i++ )) ; do
16921                 touch $DIR/$tdir/d214c/a$i
16922         done
16923
16924         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16925         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16926         ls $DIR/d214c || error "ls $DIR/d214c failed"
16927         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16928         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16929 }
16930 run_test 214 "hash-indexed directory test - bug 20133"
16931
16932 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16933 create_lnet_proc_files() {
16934         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16935 }
16936
16937 # counterpart of create_lnet_proc_files
16938 remove_lnet_proc_files() {
16939         rm -f $TMP/lnet_$1.sys
16940 }
16941
16942 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16943 # 3rd arg as regexp for body
16944 check_lnet_proc_stats() {
16945         local l=$(cat "$TMP/lnet_$1" |wc -l)
16946         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16947
16948         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16949 }
16950
16951 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16952 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16953 # optional and can be regexp for 2nd line (lnet.routes case)
16954 check_lnet_proc_entry() {
16955         local blp=2          # blp stands for 'position of 1st line of body'
16956         [ -z "$5" ] || blp=3 # lnet.routes case
16957
16958         local l=$(cat "$TMP/lnet_$1" |wc -l)
16959         # subtracting one from $blp because the body can be empty
16960         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16961
16962         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16963                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16964
16965         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16966                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16967
16968         # bail out if any unexpected line happened
16969         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16970         [ "$?" != 0 ] || error "$2 misformatted"
16971 }
16972
16973 test_215() { # for bugs 18102, 21079, 21517
16974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16975
16976         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16977         local P='[1-9][0-9]*'           # positive numeric
16978         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16979         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16980         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16981         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16982
16983         local L1 # regexp for 1st line
16984         local L2 # regexp for 2nd line (optional)
16985         local BR # regexp for the rest (body)
16986
16987         # lnet.stats should look as 11 space-separated non-negative numerics
16988         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16989         create_lnet_proc_files "stats"
16990         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16991         remove_lnet_proc_files "stats"
16992
16993         # lnet.routes should look like this:
16994         # Routing disabled/enabled
16995         # net hops priority state router
16996         # where net is a string like tcp0, hops > 0, priority >= 0,
16997         # state is up/down,
16998         # router is a string like 192.168.1.1@tcp2
16999         L1="^Routing (disabled|enabled)$"
17000         L2="^net +hops +priority +state +router$"
17001         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17002         create_lnet_proc_files "routes"
17003         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17004         remove_lnet_proc_files "routes"
17005
17006         # lnet.routers should look like this:
17007         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17008         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17009         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17010         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17011         L1="^ref +rtr_ref +alive +router$"
17012         BR="^$P +$P +(up|down) +$NID$"
17013         create_lnet_proc_files "routers"
17014         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17015         remove_lnet_proc_files "routers"
17016
17017         # lnet.peers should look like this:
17018         # nid refs state last max rtr min tx min queue
17019         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17020         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17021         # numeric (0 or >0 or <0), queue >= 0.
17022         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17023         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17024         create_lnet_proc_files "peers"
17025         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17026         remove_lnet_proc_files "peers"
17027
17028         # lnet.buffers  should look like this:
17029         # pages count credits min
17030         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17031         L1="^pages +count +credits +min$"
17032         BR="^ +$N +$N +$I +$I$"
17033         create_lnet_proc_files "buffers"
17034         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17035         remove_lnet_proc_files "buffers"
17036
17037         # lnet.nis should look like this:
17038         # nid status alive refs peer rtr max tx min
17039         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17040         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17041         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17042         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17043         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17044         create_lnet_proc_files "nis"
17045         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17046         remove_lnet_proc_files "nis"
17047
17048         # can we successfully write to lnet.stats?
17049         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17050 }
17051 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17052
17053 test_216() { # bug 20317
17054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17055         remote_ost_nodsh && skip "remote OST with nodsh"
17056
17057         local node
17058         local facets=$(get_facets OST)
17059         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17060
17061         save_lustre_params client "osc.*.contention_seconds" > $p
17062         save_lustre_params $facets \
17063                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17064         save_lustre_params $facets \
17065                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17066         save_lustre_params $facets \
17067                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17068         clear_stats osc.*.osc_stats
17069
17070         # agressive lockless i/o settings
17071         do_nodes $(comma_list $(osts_nodes)) \
17072                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17073                         ldlm.namespaces.filter-*.contended_locks=0 \
17074                         ldlm.namespaces.filter-*.contention_seconds=60"
17075         lctl set_param -n osc.*.contention_seconds=60
17076
17077         $DIRECTIO write $DIR/$tfile 0 10 4096
17078         $CHECKSTAT -s 40960 $DIR/$tfile
17079
17080         # disable lockless i/o
17081         do_nodes $(comma_list $(osts_nodes)) \
17082                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17083                         ldlm.namespaces.filter-*.contended_locks=32 \
17084                         ldlm.namespaces.filter-*.contention_seconds=0"
17085         lctl set_param -n osc.*.contention_seconds=0
17086         clear_stats osc.*.osc_stats
17087
17088         dd if=/dev/zero of=$DIR/$tfile count=0
17089         $CHECKSTAT -s 0 $DIR/$tfile
17090
17091         restore_lustre_params <$p
17092         rm -f $p
17093         rm $DIR/$tfile
17094 }
17095 run_test 216 "check lockless direct write updates file size and kms correctly"
17096
17097 test_217() { # bug 22430
17098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17099
17100         local node
17101         local nid
17102
17103         for node in $(nodes_list); do
17104                 nid=$(host_nids_address $node $NETTYPE)
17105                 if [[ $nid = *-* ]] ; then
17106                         echo "lctl ping $(h2nettype $nid)"
17107                         lctl ping $(h2nettype $nid)
17108                 else
17109                         echo "skipping $node (no hyphen detected)"
17110                 fi
17111         done
17112 }
17113 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17114
17115 test_218() {
17116        # do directio so as not to populate the page cache
17117        log "creating a 10 Mb file"
17118        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17119        log "starting reads"
17120        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17121        log "truncating the file"
17122        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17123        log "killing dd"
17124        kill %+ || true # reads might have finished
17125        echo "wait until dd is finished"
17126        wait
17127        log "removing the temporary file"
17128        rm -rf $DIR/$tfile || error "tmp file removal failed"
17129 }
17130 run_test 218 "parallel read and truncate should not deadlock"
17131
17132 test_219() {
17133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17134
17135         # write one partial page
17136         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17137         # set no grant so vvp_io_commit_write will do sync write
17138         $LCTL set_param fail_loc=0x411
17139         # write a full page at the end of file
17140         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17141
17142         $LCTL set_param fail_loc=0
17143         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17144         $LCTL set_param fail_loc=0x411
17145         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17146
17147         # LU-4201
17148         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17149         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17150 }
17151 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17152
17153 test_220() { #LU-325
17154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17155         remote_ost_nodsh && skip "remote OST with nodsh"
17156         remote_mds_nodsh && skip "remote MDS with nodsh"
17157         remote_mgs_nodsh && skip "remote MGS with nodsh"
17158
17159         local OSTIDX=0
17160
17161         # create on MDT0000 so the last_id and next_id are correct
17162         mkdir $DIR/$tdir
17163         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17164         OST=${OST%_UUID}
17165
17166         # on the mdt's osc
17167         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17168         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17169                         osp.$mdtosc_proc1.prealloc_last_id)
17170         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17171                         osp.$mdtosc_proc1.prealloc_next_id)
17172
17173         $LFS df -i
17174
17175         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17176         #define OBD_FAIL_OST_ENOINO              0x229
17177         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17178         create_pool $FSNAME.$TESTNAME || return 1
17179         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17180
17181         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17182
17183         MDSOBJS=$((last_id - next_id))
17184         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17185
17186         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17187         echo "OST still has $count kbytes free"
17188
17189         echo "create $MDSOBJS files @next_id..."
17190         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17191
17192         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17193                         osp.$mdtosc_proc1.prealloc_last_id)
17194         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17195                         osp.$mdtosc_proc1.prealloc_next_id)
17196
17197         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17198         $LFS df -i
17199
17200         echo "cleanup..."
17201
17202         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17203         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17204
17205         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17206                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17207         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17208                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17209         echo "unlink $MDSOBJS files @$next_id..."
17210         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17211 }
17212 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17213
17214 test_221() {
17215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17216
17217         dd if=`which date` of=$MOUNT/date oflag=sync
17218         chmod +x $MOUNT/date
17219
17220         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17221         $LCTL set_param fail_loc=0x80001401
17222
17223         $MOUNT/date > /dev/null
17224         rm -f $MOUNT/date
17225 }
17226 run_test 221 "make sure fault and truncate race to not cause OOM"
17227
17228 test_222a () {
17229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17230
17231         rm -rf $DIR/$tdir
17232         test_mkdir $DIR/$tdir
17233         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17234         createmany -o $DIR/$tdir/$tfile 10
17235         cancel_lru_locks mdc
17236         cancel_lru_locks osc
17237         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17238         $LCTL set_param fail_loc=0x31a
17239         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17240         $LCTL set_param fail_loc=0
17241         rm -r $DIR/$tdir
17242 }
17243 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17244
17245 test_222b () {
17246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17247
17248         rm -rf $DIR/$tdir
17249         test_mkdir $DIR/$tdir
17250         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17251         createmany -o $DIR/$tdir/$tfile 10
17252         cancel_lru_locks mdc
17253         cancel_lru_locks osc
17254         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17255         $LCTL set_param fail_loc=0x31a
17256         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17257         $LCTL set_param fail_loc=0
17258 }
17259 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17260
17261 test_223 () {
17262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17263
17264         rm -rf $DIR/$tdir
17265         test_mkdir $DIR/$tdir
17266         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17267         createmany -o $DIR/$tdir/$tfile 10
17268         cancel_lru_locks mdc
17269         cancel_lru_locks osc
17270         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17271         $LCTL set_param fail_loc=0x31b
17272         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17273         $LCTL set_param fail_loc=0
17274         rm -r $DIR/$tdir
17275 }
17276 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17277
17278 test_224a() { # LU-1039, MRP-303
17279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17280
17281         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17282         $LCTL set_param fail_loc=0x508
17283         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17284         $LCTL set_param fail_loc=0
17285         df $DIR
17286 }
17287 run_test 224a "Don't panic on bulk IO failure"
17288
17289 test_224b() { # LU-1039, MRP-303
17290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17291
17292         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17293         cancel_lru_locks osc
17294         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17295         $LCTL set_param fail_loc=0x515
17296         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17297         $LCTL set_param fail_loc=0
17298         df $DIR
17299 }
17300 run_test 224b "Don't panic on bulk IO failure"
17301
17302 test_224c() { # LU-6441
17303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17304         remote_mds_nodsh && skip "remote MDS with nodsh"
17305
17306         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17307         save_writethrough $p
17308         set_cache writethrough on
17309
17310         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17311         local at_max=$($LCTL get_param -n at_max)
17312         local timeout=$($LCTL get_param -n timeout)
17313         local test_at="at_max"
17314         local param_at="$FSNAME.sys.at_max"
17315         local test_timeout="timeout"
17316         local param_timeout="$FSNAME.sys.timeout"
17317
17318         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17319
17320         set_persistent_param_and_check client "$test_at" "$param_at" 0
17321         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17322
17323         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17324         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17325         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17326         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17327         sync
17328         do_facet ost1 "$LCTL set_param fail_loc=0"
17329
17330         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17331         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17332                 $timeout
17333
17334         $LCTL set_param -n $pages_per_rpc
17335         restore_lustre_params < $p
17336         rm -f $p
17337 }
17338 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17339
17340 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17341 test_225a () {
17342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17343         if [ -z ${MDSSURVEY} ]; then
17344                 skip_env "mds-survey not found"
17345         fi
17346         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17347                 skip "Need MDS version at least 2.2.51"
17348
17349         local mds=$(facet_host $SINGLEMDS)
17350         local target=$(do_nodes $mds 'lctl dl' |
17351                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17352
17353         local cmd1="file_count=1000 thrhi=4"
17354         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17355         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17356         local cmd="$cmd1 $cmd2 $cmd3"
17357
17358         rm -f ${TMP}/mds_survey*
17359         echo + $cmd
17360         eval $cmd || error "mds-survey with zero-stripe failed"
17361         cat ${TMP}/mds_survey*
17362         rm -f ${TMP}/mds_survey*
17363 }
17364 run_test 225a "Metadata survey sanity with zero-stripe"
17365
17366 test_225b () {
17367         if [ -z ${MDSSURVEY} ]; then
17368                 skip_env "mds-survey not found"
17369         fi
17370         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17371                 skip "Need MDS version at least 2.2.51"
17372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17373         remote_mds_nodsh && skip "remote MDS with nodsh"
17374         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17375                 skip_env "Need to mount OST to test"
17376         fi
17377
17378         local mds=$(facet_host $SINGLEMDS)
17379         local target=$(do_nodes $mds 'lctl dl' |
17380                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17381
17382         local cmd1="file_count=1000 thrhi=4"
17383         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17384         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17385         local cmd="$cmd1 $cmd2 $cmd3"
17386
17387         rm -f ${TMP}/mds_survey*
17388         echo + $cmd
17389         eval $cmd || error "mds-survey with stripe_count failed"
17390         cat ${TMP}/mds_survey*
17391         rm -f ${TMP}/mds_survey*
17392 }
17393 run_test 225b "Metadata survey sanity with stripe_count = 1"
17394
17395 mcreate_path2fid () {
17396         local mode=$1
17397         local major=$2
17398         local minor=$3
17399         local name=$4
17400         local desc=$5
17401         local path=$DIR/$tdir/$name
17402         local fid
17403         local rc
17404         local fid_path
17405
17406         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17407                 error "cannot create $desc"
17408
17409         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17410         rc=$?
17411         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17412
17413         fid_path=$($LFS fid2path $MOUNT $fid)
17414         rc=$?
17415         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17416
17417         [ "$path" == "$fid_path" ] ||
17418                 error "fid2path returned $fid_path, expected $path"
17419
17420         echo "pass with $path and $fid"
17421 }
17422
17423 test_226a () {
17424         rm -rf $DIR/$tdir
17425         mkdir -p $DIR/$tdir
17426
17427         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17428         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17429         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17430         mcreate_path2fid 0040666 0 0 dir "directory"
17431         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17432         mcreate_path2fid 0100666 0 0 file "regular file"
17433         mcreate_path2fid 0120666 0 0 link "symbolic link"
17434         mcreate_path2fid 0140666 0 0 sock "socket"
17435 }
17436 run_test 226a "call path2fid and fid2path on files of all type"
17437
17438 test_226b () {
17439         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17440
17441         local MDTIDX=1
17442
17443         rm -rf $DIR/$tdir
17444         mkdir -p $DIR/$tdir
17445         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17446                 error "create remote directory failed"
17447         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17448         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17449                                 "character special file (null)"
17450         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17451                                 "character special file (no device)"
17452         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17453         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17454                                 "block special file (loop)"
17455         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17456         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17457         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17458 }
17459 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17460
17461 test_226c () {
17462         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17463         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17464                 skip "Need MDS version at least 2.13.55"
17465
17466         local submnt=/mnt/submnt
17467         local srcfile=/etc/passwd
17468         local dstfile=$submnt/passwd
17469         local path
17470         local fid
17471
17472         rm -rf $DIR/$tdir
17473         rm -rf $submnt
17474         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17475                 error "create remote directory failed"
17476         mkdir -p $submnt || error "create $submnt failed"
17477         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17478                 error "mount $submnt failed"
17479         stack_trap "umount $submnt" EXIT
17480
17481         cp $srcfile $dstfile
17482         fid=$($LFS path2fid $dstfile)
17483         path=$($LFS fid2path $submnt "$fid")
17484         [ "$path" = "$dstfile" ] ||
17485                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17486 }
17487 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17488
17489 # LU-1299 Executing or running ldd on a truncated executable does not
17490 # cause an out-of-memory condition.
17491 test_227() {
17492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17493         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17494
17495         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17496         chmod +x $MOUNT/date
17497
17498         $MOUNT/date > /dev/null
17499         ldd $MOUNT/date > /dev/null
17500         rm -f $MOUNT/date
17501 }
17502 run_test 227 "running truncated executable does not cause OOM"
17503
17504 # LU-1512 try to reuse idle OI blocks
17505 test_228a() {
17506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17507         remote_mds_nodsh && skip "remote MDS with nodsh"
17508         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17509
17510         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17511         local myDIR=$DIR/$tdir
17512
17513         mkdir -p $myDIR
17514         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17515         $LCTL set_param fail_loc=0x80001002
17516         createmany -o $myDIR/t- 10000
17517         $LCTL set_param fail_loc=0
17518         # The guard is current the largest FID holder
17519         touch $myDIR/guard
17520         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17521                     tr -d '[')
17522         local IDX=$(($SEQ % 64))
17523
17524         do_facet $SINGLEMDS sync
17525         # Make sure journal flushed.
17526         sleep 6
17527         local blk1=$(do_facet $SINGLEMDS \
17528                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17529                      grep Blockcount | awk '{print $4}')
17530
17531         # Remove old files, some OI blocks will become idle.
17532         unlinkmany $myDIR/t- 10000
17533         # Create new files, idle OI blocks should be reused.
17534         createmany -o $myDIR/t- 2000
17535         do_facet $SINGLEMDS sync
17536         # Make sure journal flushed.
17537         sleep 6
17538         local blk2=$(do_facet $SINGLEMDS \
17539                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17540                      grep Blockcount | awk '{print $4}')
17541
17542         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17543 }
17544 run_test 228a "try to reuse idle OI blocks"
17545
17546 test_228b() {
17547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17548         remote_mds_nodsh && skip "remote MDS with nodsh"
17549         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17550
17551         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17552         local myDIR=$DIR/$tdir
17553
17554         mkdir -p $myDIR
17555         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17556         $LCTL set_param fail_loc=0x80001002
17557         createmany -o $myDIR/t- 10000
17558         $LCTL set_param fail_loc=0
17559         # The guard is current the largest FID holder
17560         touch $myDIR/guard
17561         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17562                     tr -d '[')
17563         local IDX=$(($SEQ % 64))
17564
17565         do_facet $SINGLEMDS sync
17566         # Make sure journal flushed.
17567         sleep 6
17568         local blk1=$(do_facet $SINGLEMDS \
17569                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17570                      grep Blockcount | awk '{print $4}')
17571
17572         # Remove old files, some OI blocks will become idle.
17573         unlinkmany $myDIR/t- 10000
17574
17575         # stop the MDT
17576         stop $SINGLEMDS || error "Fail to stop MDT."
17577         # remount the MDT
17578         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17579
17580         df $MOUNT || error "Fail to df."
17581         # Create new files, idle OI blocks should be reused.
17582         createmany -o $myDIR/t- 2000
17583         do_facet $SINGLEMDS sync
17584         # Make sure journal flushed.
17585         sleep 6
17586         local blk2=$(do_facet $SINGLEMDS \
17587                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17588                      grep Blockcount | awk '{print $4}')
17589
17590         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17591 }
17592 run_test 228b "idle OI blocks can be reused after MDT restart"
17593
17594 #LU-1881
17595 test_228c() {
17596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17597         remote_mds_nodsh && skip "remote MDS with nodsh"
17598         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17599
17600         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17601         local myDIR=$DIR/$tdir
17602
17603         mkdir -p $myDIR
17604         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17605         $LCTL set_param fail_loc=0x80001002
17606         # 20000 files can guarantee there are index nodes in the OI file
17607         createmany -o $myDIR/t- 20000
17608         $LCTL set_param fail_loc=0
17609         # The guard is current the largest FID holder
17610         touch $myDIR/guard
17611         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17612                     tr -d '[')
17613         local IDX=$(($SEQ % 64))
17614
17615         do_facet $SINGLEMDS sync
17616         # Make sure journal flushed.
17617         sleep 6
17618         local blk1=$(do_facet $SINGLEMDS \
17619                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17620                      grep Blockcount | awk '{print $4}')
17621
17622         # Remove old files, some OI blocks will become idle.
17623         unlinkmany $myDIR/t- 20000
17624         rm -f $myDIR/guard
17625         # The OI file should become empty now
17626
17627         # Create new files, idle OI blocks should be reused.
17628         createmany -o $myDIR/t- 2000
17629         do_facet $SINGLEMDS sync
17630         # Make sure journal flushed.
17631         sleep 6
17632         local blk2=$(do_facet $SINGLEMDS \
17633                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17634                      grep Blockcount | awk '{print $4}')
17635
17636         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17637 }
17638 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17639
17640 test_229() { # LU-2482, LU-3448
17641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17642         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17643         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17644                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17645
17646         rm -f $DIR/$tfile
17647
17648         # Create a file with a released layout and stripe count 2.
17649         $MULTIOP $DIR/$tfile H2c ||
17650                 error "failed to create file with released layout"
17651
17652         $LFS getstripe -v $DIR/$tfile
17653
17654         local pattern=$($LFS getstripe -L $DIR/$tfile)
17655         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17656
17657         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17658                 error "getstripe"
17659         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17660         stat $DIR/$tfile || error "failed to stat released file"
17661
17662         chown $RUNAS_ID $DIR/$tfile ||
17663                 error "chown $RUNAS_ID $DIR/$tfile failed"
17664
17665         chgrp $RUNAS_ID $DIR/$tfile ||
17666                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17667
17668         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17669         rm $DIR/$tfile || error "failed to remove released file"
17670 }
17671 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17672
17673 test_230a() {
17674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17675         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17676         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17677                 skip "Need MDS version at least 2.11.52"
17678
17679         local MDTIDX=1
17680
17681         test_mkdir $DIR/$tdir
17682         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17683         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17684         [ $mdt_idx -ne 0 ] &&
17685                 error "create local directory on wrong MDT $mdt_idx"
17686
17687         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17688                         error "create remote directory failed"
17689         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17690         [ $mdt_idx -ne $MDTIDX ] &&
17691                 error "create remote directory on wrong MDT $mdt_idx"
17692
17693         createmany -o $DIR/$tdir/test_230/t- 10 ||
17694                 error "create files on remote directory failed"
17695         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17696         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17697         rm -r $DIR/$tdir || error "unlink remote directory failed"
17698 }
17699 run_test 230a "Create remote directory and files under the remote directory"
17700
17701 test_230b() {
17702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17703         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17704         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17705                 skip "Need MDS version at least 2.11.52"
17706
17707         local MDTIDX=1
17708         local mdt_index
17709         local i
17710         local file
17711         local pid
17712         local stripe_count
17713         local migrate_dir=$DIR/$tdir/migrate_dir
17714         local other_dir=$DIR/$tdir/other_dir
17715
17716         test_mkdir $DIR/$tdir
17717         test_mkdir -i0 -c1 $migrate_dir
17718         test_mkdir -i0 -c1 $other_dir
17719         for ((i=0; i<10; i++)); do
17720                 mkdir -p $migrate_dir/dir_${i}
17721                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17722                         error "create files under remote dir failed $i"
17723         done
17724
17725         cp /etc/passwd $migrate_dir/$tfile
17726         cp /etc/passwd $other_dir/$tfile
17727         chattr +SAD $migrate_dir
17728         chattr +SAD $migrate_dir/$tfile
17729
17730         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17731         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17732         local old_dir_mode=$(stat -c%f $migrate_dir)
17733         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17734
17735         mkdir -p $migrate_dir/dir_default_stripe2
17736         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17737         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17738
17739         mkdir -p $other_dir
17740         ln $migrate_dir/$tfile $other_dir/luna
17741         ln $migrate_dir/$tfile $migrate_dir/sofia
17742         ln $other_dir/$tfile $migrate_dir/david
17743         ln -s $migrate_dir/$tfile $other_dir/zachary
17744         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17745         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17746
17747         local len
17748         local lnktgt
17749
17750         # inline symlink
17751         for len in 58 59 60; do
17752                 lnktgt=$(str_repeat 'l' $len)
17753                 touch $migrate_dir/$lnktgt
17754                 ln -s $lnktgt $migrate_dir/${len}char_ln
17755         done
17756
17757         # PATH_MAX
17758         for len in 4094 4095; do
17759                 lnktgt=$(str_repeat 'l' $len)
17760                 ln -s $lnktgt $migrate_dir/${len}char_ln
17761         done
17762
17763         # NAME_MAX
17764         for len in 254 255; do
17765                 touch $migrate_dir/$(str_repeat 'l' $len)
17766         done
17767
17768         $LFS migrate -m $MDTIDX $migrate_dir ||
17769                 error "fails on migrating remote dir to MDT1"
17770
17771         echo "migratate to MDT1, then checking.."
17772         for ((i = 0; i < 10; i++)); do
17773                 for file in $(find $migrate_dir/dir_${i}); do
17774                         mdt_index=$($LFS getstripe -m $file)
17775                         # broken symlink getstripe will fail
17776                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17777                                 error "$file is not on MDT${MDTIDX}"
17778                 done
17779         done
17780
17781         # the multiple link file should still in MDT0
17782         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17783         [ $mdt_index == 0 ] ||
17784                 error "$file is not on MDT${MDTIDX}"
17785
17786         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17787         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17788                 error " expect $old_dir_flag get $new_dir_flag"
17789
17790         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17791         [ "$old_file_flag" = "$new_file_flag" ] ||
17792                 error " expect $old_file_flag get $new_file_flag"
17793
17794         local new_dir_mode=$(stat -c%f $migrate_dir)
17795         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17796                 error "expect mode $old_dir_mode get $new_dir_mode"
17797
17798         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17799         [ "$old_file_mode" = "$new_file_mode" ] ||
17800                 error "expect mode $old_file_mode get $new_file_mode"
17801
17802         diff /etc/passwd $migrate_dir/$tfile ||
17803                 error "$tfile different after migration"
17804
17805         diff /etc/passwd $other_dir/luna ||
17806                 error "luna different after migration"
17807
17808         diff /etc/passwd $migrate_dir/sofia ||
17809                 error "sofia different after migration"
17810
17811         diff /etc/passwd $migrate_dir/david ||
17812                 error "david different after migration"
17813
17814         diff /etc/passwd $other_dir/zachary ||
17815                 error "zachary different after migration"
17816
17817         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17818                 error "${tfile}_ln different after migration"
17819
17820         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17821                 error "${tfile}_ln_other different after migration"
17822
17823         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17824         [ $stripe_count = 2 ] ||
17825                 error "dir strpe_count $d != 2 after migration."
17826
17827         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17828         [ $stripe_count = 2 ] ||
17829                 error "file strpe_count $d != 2 after migration."
17830
17831         #migrate back to MDT0
17832         MDTIDX=0
17833
17834         $LFS migrate -m $MDTIDX $migrate_dir ||
17835                 error "fails on migrating remote dir to MDT0"
17836
17837         echo "migrate back to MDT0, checking.."
17838         for file in $(find $migrate_dir); do
17839                 mdt_index=$($LFS getstripe -m $file)
17840                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17841                         error "$file is not on MDT${MDTIDX}"
17842         done
17843
17844         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17845         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17846                 error " expect $old_dir_flag get $new_dir_flag"
17847
17848         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17849         [ "$old_file_flag" = "$new_file_flag" ] ||
17850                 error " expect $old_file_flag get $new_file_flag"
17851
17852         local new_dir_mode=$(stat -c%f $migrate_dir)
17853         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17854                 error "expect mode $old_dir_mode get $new_dir_mode"
17855
17856         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17857         [ "$old_file_mode" = "$new_file_mode" ] ||
17858                 error "expect mode $old_file_mode get $new_file_mode"
17859
17860         diff /etc/passwd ${migrate_dir}/$tfile ||
17861                 error "$tfile different after migration"
17862
17863         diff /etc/passwd ${other_dir}/luna ||
17864                 error "luna different after migration"
17865
17866         diff /etc/passwd ${migrate_dir}/sofia ||
17867                 error "sofia different after migration"
17868
17869         diff /etc/passwd ${other_dir}/zachary ||
17870                 error "zachary different after migration"
17871
17872         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17873                 error "${tfile}_ln different after migration"
17874
17875         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17876                 error "${tfile}_ln_other different after migration"
17877
17878         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17879         [ $stripe_count = 2 ] ||
17880                 error "dir strpe_count $d != 2 after migration."
17881
17882         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17883         [ $stripe_count = 2 ] ||
17884                 error "file strpe_count $d != 2 after migration."
17885
17886         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17887 }
17888 run_test 230b "migrate directory"
17889
17890 test_230c() {
17891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17893         remote_mds_nodsh && skip "remote MDS with nodsh"
17894         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17895                 skip "Need MDS version at least 2.11.52"
17896
17897         local MDTIDX=1
17898         local total=3
17899         local mdt_index
17900         local file
17901         local migrate_dir=$DIR/$tdir/migrate_dir
17902
17903         #If migrating directory fails in the middle, all entries of
17904         #the directory is still accessiable.
17905         test_mkdir $DIR/$tdir
17906         test_mkdir -i0 -c1 $migrate_dir
17907         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17908         stat $migrate_dir
17909         createmany -o $migrate_dir/f $total ||
17910                 error "create files under ${migrate_dir} failed"
17911
17912         # fail after migrating top dir, and this will fail only once, so the
17913         # first sub file migration will fail (currently f3), others succeed.
17914         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17915         do_facet mds1 lctl set_param fail_loc=0x1801
17916         local t=$(ls $migrate_dir | wc -l)
17917         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17918                 error "migrate should fail"
17919         local u=$(ls $migrate_dir | wc -l)
17920         [ "$u" == "$t" ] || error "$u != $t during migration"
17921
17922         # add new dir/file should succeed
17923         mkdir $migrate_dir/dir ||
17924                 error "mkdir failed under migrating directory"
17925         touch $migrate_dir/file ||
17926                 error "create file failed under migrating directory"
17927
17928         # add file with existing name should fail
17929         for file in $migrate_dir/f*; do
17930                 stat $file > /dev/null || error "stat $file failed"
17931                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17932                         error "open(O_CREAT|O_EXCL) $file should fail"
17933                 $MULTIOP $file m && error "create $file should fail"
17934                 touch $DIR/$tdir/remote_dir/$tfile ||
17935                         error "touch $tfile failed"
17936                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17937                         error "link $file should fail"
17938                 mdt_index=$($LFS getstripe -m $file)
17939                 if [ $mdt_index == 0 ]; then
17940                         # file failed to migrate is not allowed to rename to
17941                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17942                                 error "rename to $file should fail"
17943                 else
17944                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17945                                 error "rename to $file failed"
17946                 fi
17947                 echo hello >> $file || error "write $file failed"
17948         done
17949
17950         # resume migration with different options should fail
17951         $LFS migrate -m 0 $migrate_dir &&
17952                 error "migrate -m 0 $migrate_dir should fail"
17953
17954         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17955                 error "migrate -c 2 $migrate_dir should fail"
17956
17957         # resume migration should succeed
17958         $LFS migrate -m $MDTIDX $migrate_dir ||
17959                 error "migrate $migrate_dir failed"
17960
17961         echo "Finish migration, then checking.."
17962         for file in $(find $migrate_dir); do
17963                 mdt_index=$($LFS getstripe -m $file)
17964                 [ $mdt_index == $MDTIDX ] ||
17965                         error "$file is not on MDT${MDTIDX}"
17966         done
17967
17968         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17969 }
17970 run_test 230c "check directory accessiblity if migration failed"
17971
17972 test_230d() {
17973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17974         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17975         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17976                 skip "Need MDS version at least 2.11.52"
17977         # LU-11235
17978         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17979
17980         local migrate_dir=$DIR/$tdir/migrate_dir
17981         local old_index
17982         local new_index
17983         local old_count
17984         local new_count
17985         local new_hash
17986         local mdt_index
17987         local i
17988         local j
17989
17990         old_index=$((RANDOM % MDSCOUNT))
17991         old_count=$((MDSCOUNT - old_index))
17992         new_index=$((RANDOM % MDSCOUNT))
17993         new_count=$((MDSCOUNT - new_index))
17994         new_hash=1 # for all_char
17995
17996         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17997         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17998
17999         test_mkdir $DIR/$tdir
18000         test_mkdir -i $old_index -c $old_count $migrate_dir
18001
18002         for ((i=0; i<100; i++)); do
18003                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18004                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18005                         error "create files under remote dir failed $i"
18006         done
18007
18008         echo -n "Migrate from MDT$old_index "
18009         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18010         echo -n "to MDT$new_index"
18011         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18012         echo
18013
18014         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18015         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18016                 error "migrate remote dir error"
18017
18018         echo "Finish migration, then checking.."
18019         for file in $(find $migrate_dir); do
18020                 mdt_index=$($LFS getstripe -m $file)
18021                 if [ $mdt_index -lt $new_index ] ||
18022                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18023                         error "$file is on MDT$mdt_index"
18024                 fi
18025         done
18026
18027         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18028 }
18029 run_test 230d "check migrate big directory"
18030
18031 test_230e() {
18032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18033         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18034         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18035                 skip "Need MDS version at least 2.11.52"
18036
18037         local i
18038         local j
18039         local a_fid
18040         local b_fid
18041
18042         mkdir -p $DIR/$tdir
18043         mkdir $DIR/$tdir/migrate_dir
18044         mkdir $DIR/$tdir/other_dir
18045         touch $DIR/$tdir/migrate_dir/a
18046         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18047         ls $DIR/$tdir/other_dir
18048
18049         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18050                 error "migrate dir fails"
18051
18052         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18053         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18054
18055         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18056         [ $mdt_index == 0 ] || error "a is not on MDT0"
18057
18058         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18059                 error "migrate dir fails"
18060
18061         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18062         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18063
18064         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18065         [ $mdt_index == 1 ] || error "a is not on MDT1"
18066
18067         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18068         [ $mdt_index == 1 ] || error "b is not on MDT1"
18069
18070         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18071         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18072
18073         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18074
18075         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18076 }
18077 run_test 230e "migrate mulitple local link files"
18078
18079 test_230f() {
18080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18081         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18082         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18083                 skip "Need MDS version at least 2.11.52"
18084
18085         local a_fid
18086         local ln_fid
18087
18088         mkdir -p $DIR/$tdir
18089         mkdir $DIR/$tdir/migrate_dir
18090         $LFS mkdir -i1 $DIR/$tdir/other_dir
18091         touch $DIR/$tdir/migrate_dir/a
18092         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18093         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18094         ls $DIR/$tdir/other_dir
18095
18096         # a should be migrated to MDT1, since no other links on MDT0
18097         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18098                 error "#1 migrate dir fails"
18099         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18100         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18101         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18102         [ $mdt_index == 1 ] || error "a is not on MDT1"
18103
18104         # a should stay on MDT1, because it is a mulitple link file
18105         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18106                 error "#2 migrate dir fails"
18107         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18108         [ $mdt_index == 1 ] || error "a is not on MDT1"
18109
18110         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18111                 error "#3 migrate dir fails"
18112
18113         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18114         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18115         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18116
18117         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18118         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18119
18120         # a should be migrated to MDT0, since no other links on MDT1
18121         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18122                 error "#4 migrate dir fails"
18123         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18124         [ $mdt_index == 0 ] || error "a is not on MDT0"
18125
18126         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18127 }
18128 run_test 230f "migrate mulitple remote link files"
18129
18130 test_230g() {
18131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18132         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18133         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18134                 skip "Need MDS version at least 2.11.52"
18135
18136         mkdir -p $DIR/$tdir/migrate_dir
18137
18138         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18139                 error "migrating dir to non-exist MDT succeeds"
18140         true
18141 }
18142 run_test 230g "migrate dir to non-exist MDT"
18143
18144 test_230h() {
18145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18146         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18147         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18148                 skip "Need MDS version at least 2.11.52"
18149
18150         local mdt_index
18151
18152         mkdir -p $DIR/$tdir/migrate_dir
18153
18154         $LFS migrate -m1 $DIR &&
18155                 error "migrating mountpoint1 should fail"
18156
18157         $LFS migrate -m1 $DIR/$tdir/.. &&
18158                 error "migrating mountpoint2 should fail"
18159
18160         # same as mv
18161         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18162                 error "migrating $tdir/migrate_dir/.. should fail"
18163
18164         true
18165 }
18166 run_test 230h "migrate .. and root"
18167
18168 test_230i() {
18169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18170         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18171         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18172                 skip "Need MDS version at least 2.11.52"
18173
18174         mkdir -p $DIR/$tdir/migrate_dir
18175
18176         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18177                 error "migration fails with a tailing slash"
18178
18179         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18180                 error "migration fails with two tailing slashes"
18181 }
18182 run_test 230i "lfs migrate -m tolerates trailing slashes"
18183
18184 test_230j() {
18185         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18186         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18187                 skip "Need MDS version at least 2.11.52"
18188
18189         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18190         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18191                 error "create $tfile failed"
18192         cat /etc/passwd > $DIR/$tdir/$tfile
18193
18194         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18195
18196         cmp /etc/passwd $DIR/$tdir/$tfile ||
18197                 error "DoM file mismatch after migration"
18198 }
18199 run_test 230j "DoM file data not changed after dir migration"
18200
18201 test_230k() {
18202         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18203         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18204                 skip "Need MDS version at least 2.11.56"
18205
18206         local total=20
18207         local files_on_starting_mdt=0
18208
18209         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18210         $LFS getdirstripe $DIR/$tdir
18211         for i in $(seq $total); do
18212                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18213                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18214                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18215         done
18216
18217         echo "$files_on_starting_mdt files on MDT0"
18218
18219         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18220         $LFS getdirstripe $DIR/$tdir
18221
18222         files_on_starting_mdt=0
18223         for i in $(seq $total); do
18224                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18225                         error "file $tfile.$i mismatch after migration"
18226                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18227                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18228         done
18229
18230         echo "$files_on_starting_mdt files on MDT1 after migration"
18231         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18232
18233         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18234         $LFS getdirstripe $DIR/$tdir
18235
18236         files_on_starting_mdt=0
18237         for i in $(seq $total); do
18238                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18239                         error "file $tfile.$i mismatch after 2nd migration"
18240                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18241                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18242         done
18243
18244         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18245         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18246
18247         true
18248 }
18249 run_test 230k "file data not changed after dir migration"
18250
18251 test_230l() {
18252         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18253         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18254                 skip "Need MDS version at least 2.11.56"
18255
18256         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18257         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18258                 error "create files under remote dir failed $i"
18259         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18260 }
18261 run_test 230l "readdir between MDTs won't crash"
18262
18263 test_230m() {
18264         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18265         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18266                 skip "Need MDS version at least 2.11.56"
18267
18268         local MDTIDX=1
18269         local mig_dir=$DIR/$tdir/migrate_dir
18270         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18271         local shortstr="b"
18272         local val
18273
18274         echo "Creating files and dirs with xattrs"
18275         test_mkdir $DIR/$tdir
18276         test_mkdir -i0 -c1 $mig_dir
18277         mkdir $mig_dir/dir
18278         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18279                 error "cannot set xattr attr1 on dir"
18280         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18281                 error "cannot set xattr attr2 on dir"
18282         touch $mig_dir/dir/f0
18283         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18284                 error "cannot set xattr attr1 on file"
18285         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18286                 error "cannot set xattr attr2 on file"
18287         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18288         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18289         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18290         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18291         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18292         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18293         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18294         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18295         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18296
18297         echo "Migrating to MDT1"
18298         $LFS migrate -m $MDTIDX $mig_dir ||
18299                 error "fails on migrating dir to MDT1"
18300
18301         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18302         echo "Checking xattrs"
18303         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18304         [ "$val" = $longstr ] ||
18305                 error "expecting xattr1 $longstr on dir, found $val"
18306         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18307         [ "$val" = $shortstr ] ||
18308                 error "expecting xattr2 $shortstr on dir, found $val"
18309         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18310         [ "$val" = $longstr ] ||
18311                 error "expecting xattr1 $longstr on file, found $val"
18312         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18313         [ "$val" = $shortstr ] ||
18314                 error "expecting xattr2 $shortstr on file, found $val"
18315 }
18316 run_test 230m "xattrs not changed after dir migration"
18317
18318 test_230n() {
18319         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18320         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18321                 skip "Need MDS version at least 2.13.53"
18322
18323         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18324         cat /etc/hosts > $DIR/$tdir/$tfile
18325         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18326         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18327
18328         cmp /etc/hosts $DIR/$tdir/$tfile ||
18329                 error "File data mismatch after migration"
18330 }
18331 run_test 230n "Dir migration with mirrored file"
18332
18333 test_230o() {
18334         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18335         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18336                 skip "Need MDS version at least 2.13.52"
18337
18338         local mdts=$(comma_list $(mdts_nodes))
18339         local timeout=100
18340
18341         local restripe_status
18342         local delta
18343         local i
18344         local j
18345
18346         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18347
18348         # in case "crush" hash type is not set
18349         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18350
18351         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18352                            mdt.*MDT0000.enable_dir_restripe)
18353         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18354         stack_trap "do_nodes $mdts $LCTL set_param \
18355                     mdt.*.enable_dir_restripe=$restripe_status"
18356
18357         mkdir $DIR/$tdir
18358         createmany -m $DIR/$tdir/f 100 ||
18359                 error "create files under remote dir failed $i"
18360         createmany -d $DIR/$tdir/d 100 ||
18361                 error "create dirs under remote dir failed $i"
18362
18363         for i in $(seq 2 $MDSCOUNT); do
18364                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18365                 $LFS setdirstripe -c $i $DIR/$tdir ||
18366                         error "split -c $i $tdir failed"
18367                 wait_update $HOSTNAME \
18368                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18369                         error "dir split not finished"
18370                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18371                         awk '/migrate/ {sum += $2} END { print sum }')
18372                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18373                 # delta is around total_files/stripe_count
18374                 [ $delta -lt $((200 /(i - 1))) ] ||
18375                         error "$delta files migrated"
18376         done
18377 }
18378 run_test 230o "dir split"
18379
18380 test_230p() {
18381         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18382         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18383                 skip "Need MDS version at least 2.13.52"
18384
18385         local mdts=$(comma_list $(mdts_nodes))
18386         local timeout=100
18387
18388         local restripe_status
18389         local delta
18390         local i
18391         local j
18392
18393         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18394
18395         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18396
18397         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18398                            mdt.*MDT0000.enable_dir_restripe)
18399         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18400         stack_trap "do_nodes $mdts $LCTL set_param \
18401                     mdt.*.enable_dir_restripe=$restripe_status"
18402
18403         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18404         createmany -m $DIR/$tdir/f 100 ||
18405                 error "create files under remote dir failed $i"
18406         createmany -d $DIR/$tdir/d 100 ||
18407                 error "create dirs under remote dir failed $i"
18408
18409         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18410                 local mdt_hash="crush"
18411
18412                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18413                 $LFS setdirstripe -c $i $DIR/$tdir ||
18414                         error "split -c $i $tdir failed"
18415                 [ $i -eq 1 ] && mdt_hash="none"
18416                 wait_update $HOSTNAME \
18417                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18418                         error "dir merge not finished"
18419                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18420                         awk '/migrate/ {sum += $2} END { print sum }')
18421                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18422                 # delta is around total_files/stripe_count
18423                 [ $delta -lt $((200 / i)) ] ||
18424                         error "$delta files migrated"
18425         done
18426 }
18427 run_test 230p "dir merge"
18428
18429 test_230q() {
18430         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18431         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18432                 skip "Need MDS version at least 2.13.52"
18433
18434         local mdts=$(comma_list $(mdts_nodes))
18435         local saved_threshold=$(do_facet mds1 \
18436                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18437         local saved_delta=$(do_facet mds1 \
18438                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18439         local threshold=100
18440         local delta=2
18441         local total=0
18442         local stripe_count=0
18443         local stripe_index
18444         local nr_files
18445
18446         # test with fewer files on ZFS
18447         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18448
18449         stack_trap "do_nodes $mdts $LCTL set_param \
18450                     mdt.*.dir_split_count=$saved_threshold"
18451         stack_trap "do_nodes $mdts $LCTL set_param \
18452                     mdt.*.dir_split_delta=$saved_delta"
18453         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18454         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18455         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18456         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18457         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18458         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18459
18460         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18461         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18462
18463         while [ $stripe_count -lt $MDSCOUNT ]; do
18464                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18465                         error "create sub files failed"
18466                 stat $DIR/$tdir > /dev/null
18467                 total=$((total + threshold * 3 / 2))
18468                 stripe_count=$((stripe_count + delta))
18469                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18470
18471                 wait_update $HOSTNAME \
18472                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18473                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18474
18475                 wait_update $HOSTNAME \
18476                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18477                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18478
18479                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18480                            grep -w $stripe_index | wc -l)
18481                 echo "$nr_files files on MDT$stripe_index after split"
18482                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18483                         error "$nr_files files on MDT$stripe_index after split"
18484
18485                 nr_files=$(ls $DIR/$tdir | wc -w)
18486                 [ $nr_files -eq $total ] ||
18487                         error "total sub files $nr_files != $total"
18488         done
18489 }
18490 run_test 230q "dir auto split"
18491
18492 test_230r() {
18493         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18494         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18495         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18496                 skip "Need MDS version at least 2.13.54"
18497
18498         # maximum amount of local locks:
18499         # parent striped dir - 2 locks
18500         # new stripe in parent to migrate to - 1 lock
18501         # source and target - 2 locks
18502         # Total 5 locks for regular file
18503         mkdir -p $DIR/$tdir
18504         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18505         touch $DIR/$tdir/dir1/eee
18506
18507         # create 4 hardlink for 4 more locks
18508         # Total: 9 locks > RS_MAX_LOCKS (8)
18509         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18510         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18511         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18512         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18513         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18514         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18515         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18516         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18517
18518         cancel_lru_locks mdc
18519
18520         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18521                 error "migrate dir fails"
18522
18523         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18524 }
18525 run_test 230r "migrate with too many local locks"
18526
18527 test_231a()
18528 {
18529         # For simplicity this test assumes that max_pages_per_rpc
18530         # is the same across all OSCs
18531         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18532         local bulk_size=$((max_pages * PAGE_SIZE))
18533         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18534                                        head -n 1)
18535
18536         mkdir -p $DIR/$tdir
18537         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18538                 error "failed to set stripe with -S ${brw_size}M option"
18539
18540         # clear the OSC stats
18541         $LCTL set_param osc.*.stats=0 &>/dev/null
18542         stop_writeback
18543
18544         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18545         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18546                 oflag=direct &>/dev/null || error "dd failed"
18547
18548         sync; sleep 1; sync # just to be safe
18549         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18550         if [ x$nrpcs != "x1" ]; then
18551                 $LCTL get_param osc.*.stats
18552                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18553         fi
18554
18555         start_writeback
18556         # Drop the OSC cache, otherwise we will read from it
18557         cancel_lru_locks osc
18558
18559         # clear the OSC stats
18560         $LCTL set_param osc.*.stats=0 &>/dev/null
18561
18562         # Client reads $bulk_size.
18563         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18564                 iflag=direct &>/dev/null || error "dd failed"
18565
18566         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18567         if [ x$nrpcs != "x1" ]; then
18568                 $LCTL get_param osc.*.stats
18569                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18570         fi
18571 }
18572 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18573
18574 test_231b() {
18575         mkdir -p $DIR/$tdir
18576         local i
18577         for i in {0..1023}; do
18578                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18579                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18580                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18581         done
18582         sync
18583 }
18584 run_test 231b "must not assert on fully utilized OST request buffer"
18585
18586 test_232a() {
18587         mkdir -p $DIR/$tdir
18588         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18589
18590         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18591         do_facet ost1 $LCTL set_param fail_loc=0x31c
18592
18593         # ignore dd failure
18594         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18595
18596         do_facet ost1 $LCTL set_param fail_loc=0
18597         umount_client $MOUNT || error "umount failed"
18598         mount_client $MOUNT || error "mount failed"
18599         stop ost1 || error "cannot stop ost1"
18600         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18601 }
18602 run_test 232a "failed lock should not block umount"
18603
18604 test_232b() {
18605         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18606                 skip "Need MDS version at least 2.10.58"
18607
18608         mkdir -p $DIR/$tdir
18609         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18610         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18611         sync
18612         cancel_lru_locks osc
18613
18614         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18615         do_facet ost1 $LCTL set_param fail_loc=0x31c
18616
18617         # ignore failure
18618         $LFS data_version $DIR/$tdir/$tfile || true
18619
18620         do_facet ost1 $LCTL set_param fail_loc=0
18621         umount_client $MOUNT || error "umount failed"
18622         mount_client $MOUNT || error "mount failed"
18623         stop ost1 || error "cannot stop ost1"
18624         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18625 }
18626 run_test 232b "failed data version lock should not block umount"
18627
18628 test_233a() {
18629         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18630                 skip "Need MDS version at least 2.3.64"
18631         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18632
18633         local fid=$($LFS path2fid $MOUNT)
18634
18635         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18636                 error "cannot access $MOUNT using its FID '$fid'"
18637 }
18638 run_test 233a "checking that OBF of the FS root succeeds"
18639
18640 test_233b() {
18641         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18642                 skip "Need MDS version at least 2.5.90"
18643         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18644
18645         local fid=$($LFS path2fid $MOUNT/.lustre)
18646
18647         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18648                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18649
18650         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18651         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18652                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18653 }
18654 run_test 233b "checking that OBF of the FS .lustre succeeds"
18655
18656 test_234() {
18657         local p="$TMP/sanityN-$TESTNAME.parameters"
18658         save_lustre_params client "llite.*.xattr_cache" > $p
18659         lctl set_param llite.*.xattr_cache 1 ||
18660                 skip_env "xattr cache is not supported"
18661
18662         mkdir -p $DIR/$tdir || error "mkdir failed"
18663         touch $DIR/$tdir/$tfile || error "touch failed"
18664         # OBD_FAIL_LLITE_XATTR_ENOMEM
18665         $LCTL set_param fail_loc=0x1405
18666         getfattr -n user.attr $DIR/$tdir/$tfile &&
18667                 error "getfattr should have failed with ENOMEM"
18668         $LCTL set_param fail_loc=0x0
18669         rm -rf $DIR/$tdir
18670
18671         restore_lustre_params < $p
18672         rm -f $p
18673 }
18674 run_test 234 "xattr cache should not crash on ENOMEM"
18675
18676 test_235() {
18677         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18678                 skip "Need MDS version at least 2.4.52"
18679
18680         flock_deadlock $DIR/$tfile
18681         local RC=$?
18682         case $RC in
18683                 0)
18684                 ;;
18685                 124) error "process hangs on a deadlock"
18686                 ;;
18687                 *) error "error executing flock_deadlock $DIR/$tfile"
18688                 ;;
18689         esac
18690 }
18691 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18692
18693 #LU-2935
18694 test_236() {
18695         check_swap_layouts_support
18696
18697         local ref1=/etc/passwd
18698         local ref2=/etc/group
18699         local file1=$DIR/$tdir/f1
18700         local file2=$DIR/$tdir/f2
18701
18702         test_mkdir -c1 $DIR/$tdir
18703         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18704         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18705         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18706         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18707         local fd=$(free_fd)
18708         local cmd="exec $fd<>$file2"
18709         eval $cmd
18710         rm $file2
18711         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18712                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18713         cmd="exec $fd>&-"
18714         eval $cmd
18715         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18716
18717         #cleanup
18718         rm -rf $DIR/$tdir
18719 }
18720 run_test 236 "Layout swap on open unlinked file"
18721
18722 # LU-4659 linkea consistency
18723 test_238() {
18724         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18725                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18726                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18727                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18728
18729         touch $DIR/$tfile
18730         ln $DIR/$tfile $DIR/$tfile.lnk
18731         touch $DIR/$tfile.new
18732         mv $DIR/$tfile.new $DIR/$tfile
18733         local fid1=$($LFS path2fid $DIR/$tfile)
18734         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18735         local path1=$($LFS fid2path $FSNAME "$fid1")
18736         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18737         local path2=$($LFS fid2path $FSNAME "$fid2")
18738         [ $tfile.lnk == $path2 ] ||
18739                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18740         rm -f $DIR/$tfile*
18741 }
18742 run_test 238 "Verify linkea consistency"
18743
18744 test_239A() { # was test_239
18745         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18746                 skip "Need MDS version at least 2.5.60"
18747
18748         local list=$(comma_list $(mdts_nodes))
18749
18750         mkdir -p $DIR/$tdir
18751         createmany -o $DIR/$tdir/f- 5000
18752         unlinkmany $DIR/$tdir/f- 5000
18753         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18754                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18755         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18756                         osp.*MDT*.sync_in_flight" | calc_sum)
18757         [ "$changes" -eq 0 ] || error "$changes not synced"
18758 }
18759 run_test 239A "osp_sync test"
18760
18761 test_239a() { #LU-5297
18762         remote_mds_nodsh && skip "remote MDS with nodsh"
18763
18764         touch $DIR/$tfile
18765         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18766         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18767         chgrp $RUNAS_GID $DIR/$tfile
18768         wait_delete_completed
18769 }
18770 run_test 239a "process invalid osp sync record correctly"
18771
18772 test_239b() { #LU-5297
18773         remote_mds_nodsh && skip "remote MDS with nodsh"
18774
18775         touch $DIR/$tfile1
18776         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18777         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18778         chgrp $RUNAS_GID $DIR/$tfile1
18779         wait_delete_completed
18780         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18781         touch $DIR/$tfile2
18782         chgrp $RUNAS_GID $DIR/$tfile2
18783         wait_delete_completed
18784 }
18785 run_test 239b "process osp sync record with ENOMEM error correctly"
18786
18787 test_240() {
18788         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18789         remote_mds_nodsh && skip "remote MDS with nodsh"
18790
18791         mkdir -p $DIR/$tdir
18792
18793         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18794                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18795         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18796                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18797
18798         umount_client $MOUNT || error "umount failed"
18799         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18800         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18801         mount_client $MOUNT || error "failed to mount client"
18802
18803         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18804         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18805 }
18806 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18807
18808 test_241_bio() {
18809         local count=$1
18810         local bsize=$2
18811
18812         for LOOP in $(seq $count); do
18813                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18814                 cancel_lru_locks $OSC || true
18815         done
18816 }
18817
18818 test_241_dio() {
18819         local count=$1
18820         local bsize=$2
18821
18822         for LOOP in $(seq $1); do
18823                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18824                         2>/dev/null
18825         done
18826 }
18827
18828 test_241a() { # was test_241
18829         local bsize=$PAGE_SIZE
18830
18831         (( bsize < 40960 )) && bsize=40960
18832         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18833         ls -la $DIR/$tfile
18834         cancel_lru_locks $OSC
18835         test_241_bio 1000 $bsize &
18836         PID=$!
18837         test_241_dio 1000 $bsize
18838         wait $PID
18839 }
18840 run_test 241a "bio vs dio"
18841
18842 test_241b() {
18843         local bsize=$PAGE_SIZE
18844
18845         (( bsize < 40960 )) && bsize=40960
18846         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18847         ls -la $DIR/$tfile
18848         test_241_dio 1000 $bsize &
18849         PID=$!
18850         test_241_dio 1000 $bsize
18851         wait $PID
18852 }
18853 run_test 241b "dio vs dio"
18854
18855 test_242() {
18856         remote_mds_nodsh && skip "remote MDS with nodsh"
18857
18858         mkdir -p $DIR/$tdir
18859         touch $DIR/$tdir/$tfile
18860
18861         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18862         do_facet mds1 lctl set_param fail_loc=0x105
18863         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18864
18865         do_facet mds1 lctl set_param fail_loc=0
18866         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18867 }
18868 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18869
18870 test_243()
18871 {
18872         test_mkdir $DIR/$tdir
18873         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18874 }
18875 run_test 243 "various group lock tests"
18876
18877 test_244a()
18878 {
18879         test_mkdir $DIR/$tdir
18880         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18881         sendfile_grouplock $DIR/$tdir/$tfile || \
18882                 error "sendfile+grouplock failed"
18883         rm -rf $DIR/$tdir
18884 }
18885 run_test 244a "sendfile with group lock tests"
18886
18887 test_244b()
18888 {
18889         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18890
18891         local threads=50
18892         local size=$((1024*1024))
18893
18894         test_mkdir $DIR/$tdir
18895         for i in $(seq 1 $threads); do
18896                 local file=$DIR/$tdir/file_$((i / 10))
18897                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18898                 local pids[$i]=$!
18899         done
18900         for i in $(seq 1 $threads); do
18901                 wait ${pids[$i]}
18902         done
18903 }
18904 run_test 244b "multi-threaded write with group lock"
18905
18906 test_245() {
18907         local flagname="multi_mod_rpcs"
18908         local connect_data_name="max_mod_rpcs"
18909         local out
18910
18911         # check if multiple modify RPCs flag is set
18912         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18913                 grep "connect_flags:")
18914         echo "$out"
18915
18916         echo "$out" | grep -qw $flagname
18917         if [ $? -ne 0 ]; then
18918                 echo "connect flag $flagname is not set"
18919                 return
18920         fi
18921
18922         # check if multiple modify RPCs data is set
18923         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18924         echo "$out"
18925
18926         echo "$out" | grep -qw $connect_data_name ||
18927                 error "import should have connect data $connect_data_name"
18928 }
18929 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18930
18931 cleanup_247() {
18932         local submount=$1
18933
18934         trap 0
18935         umount_client $submount
18936         rmdir $submount
18937 }
18938
18939 test_247a() {
18940         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18941                 grep -q subtree ||
18942                 skip_env "Fileset feature is not supported"
18943
18944         local submount=${MOUNT}_$tdir
18945
18946         mkdir $MOUNT/$tdir
18947         mkdir -p $submount || error "mkdir $submount failed"
18948         FILESET="$FILESET/$tdir" mount_client $submount ||
18949                 error "mount $submount failed"
18950         trap "cleanup_247 $submount" EXIT
18951         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18952         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18953                 error "read $MOUNT/$tdir/$tfile failed"
18954         cleanup_247 $submount
18955 }
18956 run_test 247a "mount subdir as fileset"
18957
18958 test_247b() {
18959         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18960                 skip_env "Fileset feature is not supported"
18961
18962         local submount=${MOUNT}_$tdir
18963
18964         rm -rf $MOUNT/$tdir
18965         mkdir -p $submount || error "mkdir $submount failed"
18966         SKIP_FILESET=1
18967         FILESET="$FILESET/$tdir" mount_client $submount &&
18968                 error "mount $submount should fail"
18969         rmdir $submount
18970 }
18971 run_test 247b "mount subdir that dose not exist"
18972
18973 test_247c() {
18974         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18975                 skip_env "Fileset feature is not supported"
18976
18977         local submount=${MOUNT}_$tdir
18978
18979         mkdir -p $MOUNT/$tdir/dir1
18980         mkdir -p $submount || error "mkdir $submount failed"
18981         trap "cleanup_247 $submount" EXIT
18982         FILESET="$FILESET/$tdir" mount_client $submount ||
18983                 error "mount $submount failed"
18984         local fid=$($LFS path2fid $MOUNT/)
18985         $LFS fid2path $submount $fid && error "fid2path should fail"
18986         cleanup_247 $submount
18987 }
18988 run_test 247c "running fid2path outside subdirectory root"
18989
18990 test_247d() {
18991         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18992                 skip "Fileset feature is not supported"
18993
18994         local submount=${MOUNT}_$tdir
18995
18996         mkdir -p $MOUNT/$tdir/dir1
18997         mkdir -p $submount || error "mkdir $submount failed"
18998         FILESET="$FILESET/$tdir" mount_client $submount ||
18999                 error "mount $submount failed"
19000         trap "cleanup_247 $submount" EXIT
19001
19002         local td=$submount/dir1
19003         local fid=$($LFS path2fid $td)
19004         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19005
19006         # check that we get the same pathname back
19007         local rootpath
19008         local found
19009         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19010                 echo "$rootpath $fid"
19011                 found=$($LFS fid2path $rootpath "$fid")
19012                 [ -n "found" ] || error "fid2path should succeed"
19013                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19014         done
19015         # check wrong root path format
19016         rootpath=$submount"_wrong"
19017         found=$($LFS fid2path $rootpath "$fid")
19018         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19019
19020         cleanup_247 $submount
19021 }
19022 run_test 247d "running fid2path inside subdirectory root"
19023
19024 # LU-8037
19025 test_247e() {
19026         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19027                 grep -q subtree ||
19028                 skip "Fileset feature is not supported"
19029
19030         local submount=${MOUNT}_$tdir
19031
19032         mkdir $MOUNT/$tdir
19033         mkdir -p $submount || error "mkdir $submount failed"
19034         FILESET="$FILESET/.." mount_client $submount &&
19035                 error "mount $submount should fail"
19036         rmdir $submount
19037 }
19038 run_test 247e "mount .. as fileset"
19039
19040 test_247f() {
19041         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19042         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19043                 skip "Need at least version 2.13.52"
19044         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19045                 grep -q subtree ||
19046                 skip "Fileset feature is not supported"
19047
19048         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19049         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19050                 error "mkdir remote failed"
19051         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19052         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19053                 error "mkdir striped failed"
19054         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19055
19056         local submount=${MOUNT}_$tdir
19057
19058         mkdir -p $submount || error "mkdir $submount failed"
19059
19060         local dir
19061         local fileset=$FILESET
19062
19063         for dir in $tdir/remote $tdir/remote/subdir \
19064                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19065                 FILESET="$fileset/$dir" mount_client $submount ||
19066                         error "mount $dir failed"
19067                 umount_client $submount
19068         done
19069 }
19070 run_test 247f "mount striped or remote directory as fileset"
19071
19072 test_248a() {
19073         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19074         [ -z "$fast_read_sav" ] && skip "no fast read support"
19075
19076         # create a large file for fast read verification
19077         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19078
19079         # make sure the file is created correctly
19080         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19081                 { rm -f $DIR/$tfile; skip "file creation error"; }
19082
19083         echo "Test 1: verify that fast read is 4 times faster on cache read"
19084
19085         # small read with fast read enabled
19086         $LCTL set_param -n llite.*.fast_read=1
19087         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19088                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19089                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19090         # small read with fast read disabled
19091         $LCTL set_param -n llite.*.fast_read=0
19092         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19093                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19094                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19095
19096         # verify that fast read is 4 times faster for cache read
19097         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19098                 error_not_in_vm "fast read was not 4 times faster: " \
19099                            "$t_fast vs $t_slow"
19100
19101         echo "Test 2: verify the performance between big and small read"
19102         $LCTL set_param -n llite.*.fast_read=1
19103
19104         # 1k non-cache read
19105         cancel_lru_locks osc
19106         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19107                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19108                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19109
19110         # 1M non-cache read
19111         cancel_lru_locks osc
19112         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19113                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19114                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19115
19116         # verify that big IO is not 4 times faster than small IO
19117         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19118                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19119
19120         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19121         rm -f $DIR/$tfile
19122 }
19123 run_test 248a "fast read verification"
19124
19125 test_248b() {
19126         # Default short_io_bytes=16384, try both smaller and larger sizes.
19127         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19128         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19129         echo "bs=53248 count=113 normal buffered write"
19130         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19131                 error "dd of initial data file failed"
19132         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19133
19134         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19135         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19136                 error "dd with sync normal writes failed"
19137         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19138
19139         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19140         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19141                 error "dd with sync small writes failed"
19142         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19143
19144         cancel_lru_locks osc
19145
19146         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19147         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19148         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19149         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19150                 iflag=direct || error "dd with O_DIRECT small read failed"
19151         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19152         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19153                 error "compare $TMP/$tfile.1 failed"
19154
19155         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19156         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19157
19158         # just to see what the maximum tunable value is, and test parsing
19159         echo "test invalid parameter 2MB"
19160         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19161                 error "too-large short_io_bytes allowed"
19162         echo "test maximum parameter 512KB"
19163         # if we can set a larger short_io_bytes, run test regardless of version
19164         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19165                 # older clients may not allow setting it this large, that's OK
19166                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19167                         skip "Need at least client version 2.13.50"
19168                 error "medium short_io_bytes failed"
19169         fi
19170         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19171         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19172
19173         echo "test large parameter 64KB"
19174         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19175         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19176
19177         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19178         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19179                 error "dd with sync large writes failed"
19180         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19181
19182         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19183         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19184         num=$((113 * 4096 / PAGE_SIZE))
19185         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19186         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19187                 error "dd with O_DIRECT large writes failed"
19188         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19189                 error "compare $DIR/$tfile.3 failed"
19190
19191         cancel_lru_locks osc
19192
19193         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19194         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19195                 error "dd with O_DIRECT large read failed"
19196         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19197                 error "compare $TMP/$tfile.2 failed"
19198
19199         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19200         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19201                 error "dd with O_DIRECT large read failed"
19202         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19203                 error "compare $TMP/$tfile.3 failed"
19204 }
19205 run_test 248b "test short_io read and write for both small and large sizes"
19206
19207 test_249() { # LU-7890
19208         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19209                 skip "Need at least version 2.8.54"
19210
19211         rm -f $DIR/$tfile
19212         $LFS setstripe -c 1 $DIR/$tfile
19213         # Offset 2T == 4k * 512M
19214         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19215                 error "dd to 2T offset failed"
19216 }
19217 run_test 249 "Write above 2T file size"
19218
19219 test_250() {
19220         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19221          && skip "no 16TB file size limit on ZFS"
19222
19223         $LFS setstripe -c 1 $DIR/$tfile
19224         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19225         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19226         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19227         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19228                 conv=notrunc,fsync && error "append succeeded"
19229         return 0
19230 }
19231 run_test 250 "Write above 16T limit"
19232
19233 test_251() {
19234         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19235
19236         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19237         #Skip once - writing the first stripe will succeed
19238         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19239         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19240                 error "short write happened"
19241
19242         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19243         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19244                 error "short read happened"
19245
19246         rm -f $DIR/$tfile
19247 }
19248 run_test 251 "Handling short read and write correctly"
19249
19250 test_252() {
19251         remote_mds_nodsh && skip "remote MDS with nodsh"
19252         remote_ost_nodsh && skip "remote OST with nodsh"
19253         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19254                 skip_env "ldiskfs only test"
19255         fi
19256
19257         local tgt
19258         local dev
19259         local out
19260         local uuid
19261         local num
19262         local gen
19263
19264         # check lr_reader on OST0000
19265         tgt=ost1
19266         dev=$(facet_device $tgt)
19267         out=$(do_facet $tgt $LR_READER $dev)
19268         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19269         echo "$out"
19270         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19271         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19272                 error "Invalid uuid returned by $LR_READER on target $tgt"
19273         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19274
19275         # check lr_reader -c on MDT0000
19276         tgt=mds1
19277         dev=$(facet_device $tgt)
19278         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19279                 skip "$LR_READER does not support additional options"
19280         fi
19281         out=$(do_facet $tgt $LR_READER -c $dev)
19282         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19283         echo "$out"
19284         num=$(echo "$out" | grep -c "mdtlov")
19285         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19286                 error "Invalid number of mdtlov clients returned by $LR_READER"
19287         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19288
19289         # check lr_reader -cr on MDT0000
19290         out=$(do_facet $tgt $LR_READER -cr $dev)
19291         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19292         echo "$out"
19293         echo "$out" | grep -q "^reply_data:$" ||
19294                 error "$LR_READER should have returned 'reply_data' section"
19295         num=$(echo "$out" | grep -c "client_generation")
19296         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19297 }
19298 run_test 252 "check lr_reader tool"
19299
19300 test_253() {
19301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19302         remote_mds_nodsh && skip "remote MDS with nodsh"
19303         remote_mgs_nodsh && skip "remote MGS with nodsh"
19304
19305         local ostidx=0
19306         local rc=0
19307         local ost_name=$(ostname_from_index $ostidx)
19308
19309         # on the mdt's osc
19310         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19311         do_facet $SINGLEMDS $LCTL get_param -n \
19312                 osp.$mdtosc_proc1.reserved_mb_high ||
19313                 skip  "remote MDS does not support reserved_mb_high"
19314
19315         rm -rf $DIR/$tdir
19316         wait_mds_ost_sync
19317         wait_delete_completed
19318         mkdir $DIR/$tdir
19319
19320         pool_add $TESTNAME || error "Pool creation failed"
19321         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19322
19323         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19324                 error "Setstripe failed"
19325
19326         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19327
19328         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19329                     grep "watermarks")
19330         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19331
19332         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19333                         osp.$mdtosc_proc1.prealloc_status)
19334         echo "prealloc_status $oa_status"
19335
19336         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19337                 error "File creation should fail"
19338
19339         #object allocation was stopped, but we still able to append files
19340         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19341                 oflag=append || error "Append failed"
19342
19343         rm -f $DIR/$tdir/$tfile.0
19344
19345         # For this test, we want to delete the files we created to go out of
19346         # space but leave the watermark, so we remain nearly out of space
19347         ost_watermarks_enospc_delete_files $tfile $ostidx
19348
19349         wait_delete_completed
19350
19351         sleep_maxage
19352
19353         for i in $(seq 10 12); do
19354                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19355                         2>/dev/null || error "File creation failed after rm"
19356         done
19357
19358         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19359                         osp.$mdtosc_proc1.prealloc_status)
19360         echo "prealloc_status $oa_status"
19361
19362         if (( oa_status != 0 )); then
19363                 error "Object allocation still disable after rm"
19364         fi
19365 }
19366 run_test 253 "Check object allocation limit"
19367
19368 test_254() {
19369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19370         remote_mds_nodsh && skip "remote MDS with nodsh"
19371         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19372                 skip "MDS does not support changelog_size"
19373
19374         local cl_user
19375         local MDT0=$(facet_svc $SINGLEMDS)
19376
19377         changelog_register || error "changelog_register failed"
19378
19379         changelog_clear 0 || error "changelog_clear failed"
19380
19381         local size1=$(do_facet $SINGLEMDS \
19382                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19383         echo "Changelog size $size1"
19384
19385         rm -rf $DIR/$tdir
19386         $LFS mkdir -i 0 $DIR/$tdir
19387         # change something
19388         mkdir -p $DIR/$tdir/pics/2008/zachy
19389         touch $DIR/$tdir/pics/2008/zachy/timestamp
19390         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19391         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19392         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19393         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19394         rm $DIR/$tdir/pics/desktop.jpg
19395
19396         local size2=$(do_facet $SINGLEMDS \
19397                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19398         echo "Changelog size after work $size2"
19399
19400         (( $size2 > $size1 )) ||
19401                 error "new Changelog size=$size2 less than old size=$size1"
19402 }
19403 run_test 254 "Check changelog size"
19404
19405 ladvise_no_type()
19406 {
19407         local type=$1
19408         local file=$2
19409
19410         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19411                 awk -F: '{print $2}' | grep $type > /dev/null
19412         if [ $? -ne 0 ]; then
19413                 return 0
19414         fi
19415         return 1
19416 }
19417
19418 ladvise_no_ioctl()
19419 {
19420         local file=$1
19421
19422         lfs ladvise -a willread $file > /dev/null 2>&1
19423         if [ $? -eq 0 ]; then
19424                 return 1
19425         fi
19426
19427         lfs ladvise -a willread $file 2>&1 |
19428                 grep "Inappropriate ioctl for device" > /dev/null
19429         if [ $? -eq 0 ]; then
19430                 return 0
19431         fi
19432         return 1
19433 }
19434
19435 percent() {
19436         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19437 }
19438
19439 # run a random read IO workload
19440 # usage: random_read_iops <filename> <filesize> <iosize>
19441 random_read_iops() {
19442         local file=$1
19443         local fsize=$2
19444         local iosize=${3:-4096}
19445
19446         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19447                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19448 }
19449
19450 drop_file_oss_cache() {
19451         local file="$1"
19452         local nodes="$2"
19453
19454         $LFS ladvise -a dontneed $file 2>/dev/null ||
19455                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19456 }
19457
19458 ladvise_willread_performance()
19459 {
19460         local repeat=10
19461         local average_origin=0
19462         local average_cache=0
19463         local average_ladvise=0
19464
19465         for ((i = 1; i <= $repeat; i++)); do
19466                 echo "Iter $i/$repeat: reading without willread hint"
19467                 cancel_lru_locks osc
19468                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19469                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19470                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19471                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19472
19473                 cancel_lru_locks osc
19474                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19475                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19476                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19477
19478                 cancel_lru_locks osc
19479                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19480                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19481                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19482                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19483                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19484         done
19485         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19486         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19487         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19488
19489         speedup_cache=$(percent $average_cache $average_origin)
19490         speedup_ladvise=$(percent $average_ladvise $average_origin)
19491
19492         echo "Average uncached read: $average_origin"
19493         echo "Average speedup with OSS cached read: " \
19494                 "$average_cache = +$speedup_cache%"
19495         echo "Average speedup with ladvise willread: " \
19496                 "$average_ladvise = +$speedup_ladvise%"
19497
19498         local lowest_speedup=20
19499         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19500                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19501                         "got $average_cache%. Skipping ladvise willread check."
19502                 return 0
19503         fi
19504
19505         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19506         # it is still good to run until then to exercise 'ladvise willread'
19507         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19508                 [ "$ost1_FSTYPE" = "zfs" ] &&
19509                 echo "osd-zfs does not support dontneed or drop_caches" &&
19510                 return 0
19511
19512         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19513         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19514                 error_not_in_vm "Speedup with willread is less than " \
19515                         "$lowest_speedup%, got $average_ladvise%"
19516 }
19517
19518 test_255a() {
19519         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19520                 skip "lustre < 2.8.54 does not support ladvise "
19521         remote_ost_nodsh && skip "remote OST with nodsh"
19522
19523         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19524
19525         ladvise_no_type willread $DIR/$tfile &&
19526                 skip "willread ladvise is not supported"
19527
19528         ladvise_no_ioctl $DIR/$tfile &&
19529                 skip "ladvise ioctl is not supported"
19530
19531         local size_mb=100
19532         local size=$((size_mb * 1048576))
19533         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19534                 error "dd to $DIR/$tfile failed"
19535
19536         lfs ladvise -a willread $DIR/$tfile ||
19537                 error "Ladvise failed with no range argument"
19538
19539         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19540                 error "Ladvise failed with no -l or -e argument"
19541
19542         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19543                 error "Ladvise failed with only -e argument"
19544
19545         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19546                 error "Ladvise failed with only -l argument"
19547
19548         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19549                 error "End offset should not be smaller than start offset"
19550
19551         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19552                 error "End offset should not be equal to start offset"
19553
19554         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19555                 error "Ladvise failed with overflowing -s argument"
19556
19557         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19558                 error "Ladvise failed with overflowing -e argument"
19559
19560         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19561                 error "Ladvise failed with overflowing -l argument"
19562
19563         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19564                 error "Ladvise succeeded with conflicting -l and -e arguments"
19565
19566         echo "Synchronous ladvise should wait"
19567         local delay=4
19568 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19569         do_nodes $(comma_list $(osts_nodes)) \
19570                 $LCTL set_param fail_val=$delay fail_loc=0x237
19571
19572         local start_ts=$SECONDS
19573         lfs ladvise -a willread $DIR/$tfile ||
19574                 error "Ladvise failed with no range argument"
19575         local end_ts=$SECONDS
19576         local inteval_ts=$((end_ts - start_ts))
19577
19578         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19579                 error "Synchronous advice didn't wait reply"
19580         fi
19581
19582         echo "Asynchronous ladvise shouldn't wait"
19583         local start_ts=$SECONDS
19584         lfs ladvise -a willread -b $DIR/$tfile ||
19585                 error "Ladvise failed with no range argument"
19586         local end_ts=$SECONDS
19587         local inteval_ts=$((end_ts - start_ts))
19588
19589         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19590                 error "Asynchronous advice blocked"
19591         fi
19592
19593         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19594         ladvise_willread_performance
19595 }
19596 run_test 255a "check 'lfs ladvise -a willread'"
19597
19598 facet_meminfo() {
19599         local facet=$1
19600         local info=$2
19601
19602         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19603 }
19604
19605 test_255b() {
19606         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19607                 skip "lustre < 2.8.54 does not support ladvise "
19608         remote_ost_nodsh && skip "remote OST with nodsh"
19609
19610         lfs setstripe -c 1 -i 0 $DIR/$tfile
19611
19612         ladvise_no_type dontneed $DIR/$tfile &&
19613                 skip "dontneed ladvise is not supported"
19614
19615         ladvise_no_ioctl $DIR/$tfile &&
19616                 skip "ladvise ioctl is not supported"
19617
19618         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19619                 [ "$ost1_FSTYPE" = "zfs" ] &&
19620                 skip "zfs-osd does not support 'ladvise dontneed'"
19621
19622         local size_mb=100
19623         local size=$((size_mb * 1048576))
19624         # In order to prevent disturbance of other processes, only check 3/4
19625         # of the memory usage
19626         local kibibytes=$((size_mb * 1024 * 3 / 4))
19627
19628         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19629                 error "dd to $DIR/$tfile failed"
19630
19631         #force write to complete before dropping OST cache & checking memory
19632         sync
19633
19634         local total=$(facet_meminfo ost1 MemTotal)
19635         echo "Total memory: $total KiB"
19636
19637         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19638         local before_read=$(facet_meminfo ost1 Cached)
19639         echo "Cache used before read: $before_read KiB"
19640
19641         lfs ladvise -a willread $DIR/$tfile ||
19642                 error "Ladvise willread failed"
19643         local after_read=$(facet_meminfo ost1 Cached)
19644         echo "Cache used after read: $after_read KiB"
19645
19646         lfs ladvise -a dontneed $DIR/$tfile ||
19647                 error "Ladvise dontneed again failed"
19648         local no_read=$(facet_meminfo ost1 Cached)
19649         echo "Cache used after dontneed ladvise: $no_read KiB"
19650
19651         if [ $total -lt $((before_read + kibibytes)) ]; then
19652                 echo "Memory is too small, abort checking"
19653                 return 0
19654         fi
19655
19656         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19657                 error "Ladvise willread should use more memory" \
19658                         "than $kibibytes KiB"
19659         fi
19660
19661         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19662                 error "Ladvise dontneed should release more memory" \
19663                         "than $kibibytes KiB"
19664         fi
19665 }
19666 run_test 255b "check 'lfs ladvise -a dontneed'"
19667
19668 test_255c() {
19669         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19670                 skip "lustre < 2.10.50 does not support lockahead"
19671
19672         local count
19673         local new_count
19674         local difference
19675         local i
19676         local rc
19677
19678         test_mkdir -p $DIR/$tdir
19679         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19680
19681         #test 10 returns only success/failure
19682         i=10
19683         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19684         rc=$?
19685         if [ $rc -eq 255 ]; then
19686                 error "Ladvise test${i} failed, ${rc}"
19687         fi
19688
19689         #test 11 counts lock enqueue requests, all others count new locks
19690         i=11
19691         count=$(do_facet ost1 \
19692                 $LCTL get_param -n ost.OSS.ost.stats)
19693         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19694
19695         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19696         rc=$?
19697         if [ $rc -eq 255 ]; then
19698                 error "Ladvise test${i} failed, ${rc}"
19699         fi
19700
19701         new_count=$(do_facet ost1 \
19702                 $LCTL get_param -n ost.OSS.ost.stats)
19703         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19704                    awk '{ print $2 }')
19705
19706         difference="$((new_count - count))"
19707         if [ $difference -ne $rc ]; then
19708                 error "Ladvise test${i}, bad enqueue count, returned " \
19709                       "${rc}, actual ${difference}"
19710         fi
19711
19712         for i in $(seq 12 21); do
19713                 # If we do not do this, we run the risk of having too many
19714                 # locks and starting lock cancellation while we are checking
19715                 # lock counts.
19716                 cancel_lru_locks osc
19717
19718                 count=$($LCTL get_param -n \
19719                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19720
19721                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19722                 rc=$?
19723                 if [ $rc -eq 255 ]; then
19724                         error "Ladvise test ${i} failed, ${rc}"
19725                 fi
19726
19727                 new_count=$($LCTL get_param -n \
19728                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19729                 difference="$((new_count - count))"
19730
19731                 # Test 15 output is divided by 100 to map down to valid return
19732                 if [ $i -eq 15 ]; then
19733                         rc="$((rc * 100))"
19734                 fi
19735
19736                 if [ $difference -ne $rc ]; then
19737                         error "Ladvise test ${i}, bad lock count, returned " \
19738                               "${rc}, actual ${difference}"
19739                 fi
19740         done
19741
19742         #test 22 returns only success/failure
19743         i=22
19744         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19745         rc=$?
19746         if [ $rc -eq 255 ]; then
19747                 error "Ladvise test${i} failed, ${rc}"
19748         fi
19749 }
19750 run_test 255c "suite of ladvise lockahead tests"
19751
19752 test_256() {
19753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19754         remote_mds_nodsh && skip "remote MDS with nodsh"
19755         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19756         changelog_users $SINGLEMDS | grep "^cl" &&
19757                 skip "active changelog user"
19758
19759         local cl_user
19760         local cat_sl
19761         local mdt_dev
19762
19763         mdt_dev=$(mdsdevname 1)
19764         echo $mdt_dev
19765
19766         changelog_register || error "changelog_register failed"
19767
19768         rm -rf $DIR/$tdir
19769         mkdir -p $DIR/$tdir
19770
19771         changelog_clear 0 || error "changelog_clear failed"
19772
19773         # change something
19774         touch $DIR/$tdir/{1..10}
19775
19776         # stop the MDT
19777         stop $SINGLEMDS || error "Fail to stop MDT"
19778
19779         # remount the MDT
19780
19781         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19782
19783         #after mount new plainllog is used
19784         touch $DIR/$tdir/{11..19}
19785         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19786         stack_trap "rm -f $tmpfile"
19787         cat_sl=$(do_facet $SINGLEMDS "sync; \
19788                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19789                  llog_reader $tmpfile | grep -c type=1064553b")
19790         do_facet $SINGLEMDS llog_reader $tmpfile
19791
19792         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19793
19794         changelog_clear 0 || error "changelog_clear failed"
19795
19796         cat_sl=$(do_facet $SINGLEMDS "sync; \
19797                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19798                  llog_reader $tmpfile | grep -c type=1064553b")
19799
19800         if (( cat_sl == 2 )); then
19801                 error "Empty plain llog was not deleted from changelog catalog"
19802         elif (( cat_sl != 1 )); then
19803                 error "Active plain llog shouldn't be deleted from catalog"
19804         fi
19805 }
19806 run_test 256 "Check llog delete for empty and not full state"
19807
19808 test_257() {
19809         remote_mds_nodsh && skip "remote MDS with nodsh"
19810         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19811                 skip "Need MDS version at least 2.8.55"
19812
19813         test_mkdir $DIR/$tdir
19814
19815         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19816                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19817         stat $DIR/$tdir
19818
19819 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19820         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19821         local facet=mds$((mdtidx + 1))
19822         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19823         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19824
19825         stop $facet || error "stop MDS failed"
19826         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19827                 error "start MDS fail"
19828         wait_recovery_complete $facet
19829 }
19830 run_test 257 "xattr locks are not lost"
19831
19832 # Verify we take the i_mutex when security requires it
19833 test_258a() {
19834 #define OBD_FAIL_IMUTEX_SEC 0x141c
19835         $LCTL set_param fail_loc=0x141c
19836         touch $DIR/$tfile
19837         chmod u+s $DIR/$tfile
19838         chmod a+rwx $DIR/$tfile
19839         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19840         RC=$?
19841         if [ $RC -ne 0 ]; then
19842                 error "error, failed to take i_mutex, rc=$?"
19843         fi
19844         rm -f $DIR/$tfile
19845 }
19846 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19847
19848 # Verify we do NOT take the i_mutex in the normal case
19849 test_258b() {
19850 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19851         $LCTL set_param fail_loc=0x141d
19852         touch $DIR/$tfile
19853         chmod a+rwx $DIR
19854         chmod a+rw $DIR/$tfile
19855         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19856         RC=$?
19857         if [ $RC -ne 0 ]; then
19858                 error "error, took i_mutex unnecessarily, rc=$?"
19859         fi
19860         rm -f $DIR/$tfile
19861
19862 }
19863 run_test 258b "verify i_mutex security behavior"
19864
19865 test_259() {
19866         local file=$DIR/$tfile
19867         local before
19868         local after
19869
19870         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19871
19872         stack_trap "rm -f $file" EXIT
19873
19874         wait_delete_completed
19875         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19876         echo "before: $before"
19877
19878         $LFS setstripe -i 0 -c 1 $file
19879         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19880         sync_all_data
19881         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19882         echo "after write: $after"
19883
19884 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19885         do_facet ost1 $LCTL set_param fail_loc=0x2301
19886         $TRUNCATE $file 0
19887         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19888         echo "after truncate: $after"
19889
19890         stop ost1
19891         do_facet ost1 $LCTL set_param fail_loc=0
19892         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19893         sleep 2
19894         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19895         echo "after restart: $after"
19896         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19897                 error "missing truncate?"
19898
19899         return 0
19900 }
19901 run_test 259 "crash at delayed truncate"
19902
19903 test_260() {
19904 #define OBD_FAIL_MDC_CLOSE               0x806
19905         $LCTL set_param fail_loc=0x80000806
19906         touch $DIR/$tfile
19907
19908 }
19909 run_test 260 "Check mdc_close fail"
19910
19911 ### Data-on-MDT sanity tests ###
19912 test_270a() {
19913         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19914                 skip "Need MDS version at least 2.10.55 for DoM"
19915
19916         # create DoM file
19917         local dom=$DIR/$tdir/dom_file
19918         local tmp=$DIR/$tdir/tmp_file
19919
19920         mkdir -p $DIR/$tdir
19921
19922         # basic checks for DoM component creation
19923         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19924                 error "Can set MDT layout to non-first entry"
19925
19926         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19927                 error "Can define multiple entries as MDT layout"
19928
19929         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19930
19931         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19932         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19933         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19934
19935         local mdtidx=$($LFS getstripe -m $dom)
19936         local mdtname=MDT$(printf %04x $mdtidx)
19937         local facet=mds$((mdtidx + 1))
19938         local space_check=1
19939
19940         # Skip free space checks with ZFS
19941         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19942
19943         # write
19944         sync
19945         local size_tmp=$((65536 * 3))
19946         local mdtfree1=$(do_facet $facet \
19947                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19948
19949         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19950         # check also direct IO along write
19951         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19952         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19953         sync
19954         cmp $tmp $dom || error "file data is different"
19955         [ $(stat -c%s $dom) == $size_tmp ] ||
19956                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19957         if [ $space_check == 1 ]; then
19958                 local mdtfree2=$(do_facet $facet \
19959                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19960
19961                 # increase in usage from by $size_tmp
19962                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19963                         error "MDT free space wrong after write: " \
19964                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19965         fi
19966
19967         # truncate
19968         local size_dom=10000
19969
19970         $TRUNCATE $dom $size_dom
19971         [ $(stat -c%s $dom) == $size_dom ] ||
19972                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19973         if [ $space_check == 1 ]; then
19974                 mdtfree1=$(do_facet $facet \
19975                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19976                 # decrease in usage from $size_tmp to new $size_dom
19977                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19978                   $(((size_tmp - size_dom) / 1024)) ] ||
19979                         error "MDT free space is wrong after truncate: " \
19980                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19981         fi
19982
19983         # append
19984         cat $tmp >> $dom
19985         sync
19986         size_dom=$((size_dom + size_tmp))
19987         [ $(stat -c%s $dom) == $size_dom ] ||
19988                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19989         if [ $space_check == 1 ]; then
19990                 mdtfree2=$(do_facet $facet \
19991                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19992                 # increase in usage by $size_tmp from previous
19993                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19994                         error "MDT free space is wrong after append: " \
19995                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19996         fi
19997
19998         # delete
19999         rm $dom
20000         if [ $space_check == 1 ]; then
20001                 mdtfree1=$(do_facet $facet \
20002                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20003                 # decrease in usage by $size_dom from previous
20004                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20005                         error "MDT free space is wrong after removal: " \
20006                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20007         fi
20008
20009         # combined striping
20010         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20011                 error "Can't create DoM + OST striping"
20012
20013         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20014         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20015         # check also direct IO along write
20016         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20017         sync
20018         cmp $tmp $dom || error "file data is different"
20019         [ $(stat -c%s $dom) == $size_tmp ] ||
20020                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20021         rm $dom $tmp
20022
20023         return 0
20024 }
20025 run_test 270a "DoM: basic functionality tests"
20026
20027 test_270b() {
20028         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20029                 skip "Need MDS version at least 2.10.55"
20030
20031         local dom=$DIR/$tdir/dom_file
20032         local max_size=1048576
20033
20034         mkdir -p $DIR/$tdir
20035         $LFS setstripe -E $max_size -L mdt $dom
20036
20037         # truncate over the limit
20038         $TRUNCATE $dom $(($max_size + 1)) &&
20039                 error "successful truncate over the maximum size"
20040         # write over the limit
20041         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20042                 error "successful write over the maximum size"
20043         # append over the limit
20044         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20045         echo "12345" >> $dom && error "successful append over the maximum size"
20046         rm $dom
20047
20048         return 0
20049 }
20050 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20051
20052 test_270c() {
20053         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20054                 skip "Need MDS version at least 2.10.55"
20055
20056         mkdir -p $DIR/$tdir
20057         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20058
20059         # check files inherit DoM EA
20060         touch $DIR/$tdir/first
20061         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20062                 error "bad pattern"
20063         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20064                 error "bad stripe count"
20065         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20066                 error "bad stripe size"
20067
20068         # check directory inherits DoM EA and uses it as default
20069         mkdir $DIR/$tdir/subdir
20070         touch $DIR/$tdir/subdir/second
20071         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20072                 error "bad pattern in sub-directory"
20073         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20074                 error "bad stripe count in sub-directory"
20075         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20076                 error "bad stripe size in sub-directory"
20077         return 0
20078 }
20079 run_test 270c "DoM: DoM EA inheritance tests"
20080
20081 test_270d() {
20082         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20083                 skip "Need MDS version at least 2.10.55"
20084
20085         mkdir -p $DIR/$tdir
20086         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20087
20088         # inherit default DoM striping
20089         mkdir $DIR/$tdir/subdir
20090         touch $DIR/$tdir/subdir/f1
20091
20092         # change default directory striping
20093         $LFS setstripe -c 1 $DIR/$tdir/subdir
20094         touch $DIR/$tdir/subdir/f2
20095         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20096                 error "wrong default striping in file 2"
20097         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20098                 error "bad pattern in file 2"
20099         return 0
20100 }
20101 run_test 270d "DoM: change striping from DoM to RAID0"
20102
20103 test_270e() {
20104         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20105                 skip "Need MDS version at least 2.10.55"
20106
20107         mkdir -p $DIR/$tdir/dom
20108         mkdir -p $DIR/$tdir/norm
20109         DOMFILES=20
20110         NORMFILES=10
20111         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20112         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20113
20114         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20115         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20116
20117         # find DoM files by layout
20118         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20119         [ $NUM -eq  $DOMFILES ] ||
20120                 error "lfs find -L: found $NUM, expected $DOMFILES"
20121         echo "Test 1: lfs find 20 DOM files by layout: OK"
20122
20123         # there should be 1 dir with default DOM striping
20124         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20125         [ $NUM -eq  1 ] ||
20126                 error "lfs find -L: found $NUM, expected 1 dir"
20127         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20128
20129         # find DoM files by stripe size
20130         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20131         [ $NUM -eq  $DOMFILES ] ||
20132                 error "lfs find -S: found $NUM, expected $DOMFILES"
20133         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20134
20135         # find files by stripe offset except DoM files
20136         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20137         [ $NUM -eq  $NORMFILES ] ||
20138                 error "lfs find -i: found $NUM, expected $NORMFILES"
20139         echo "Test 5: lfs find no DOM files by stripe index: OK"
20140         return 0
20141 }
20142 run_test 270e "DoM: lfs find with DoM files test"
20143
20144 test_270f() {
20145         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20146                 skip "Need MDS version at least 2.10.55"
20147
20148         local mdtname=${FSNAME}-MDT0000-mdtlov
20149         local dom=$DIR/$tdir/dom_file
20150         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20151                                                 lod.$mdtname.dom_stripesize)
20152         local dom_limit=131072
20153
20154         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20155         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20156                                                 lod.$mdtname.dom_stripesize)
20157         [ ${dom_limit} -eq ${dom_current} ] ||
20158                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20159
20160         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20161         $LFS setstripe -d $DIR/$tdir
20162         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20163                 error "Can't set directory default striping"
20164
20165         # exceed maximum stripe size
20166         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20167                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20168         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20169                 error "Able to create DoM component size more than LOD limit"
20170
20171         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20172         dom_current=$(do_facet mds1 $LCTL get_param -n \
20173                                                 lod.$mdtname.dom_stripesize)
20174         [ 0 -eq ${dom_current} ] ||
20175                 error "Can't set zero DoM stripe limit"
20176         rm $dom
20177
20178         # attempt to create DoM file on server with disabled DoM should
20179         # remove DoM entry from layout and be succeed
20180         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20181                 error "Can't create DoM file (DoM is disabled)"
20182         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20183                 error "File has DoM component while DoM is disabled"
20184         rm $dom
20185
20186         # attempt to create DoM file with only DoM stripe should return error
20187         $LFS setstripe -E $dom_limit -L mdt $dom &&
20188                 error "Able to create DoM-only file while DoM is disabled"
20189
20190         # too low values to be aligned with smallest stripe size 64K
20191         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20192         dom_current=$(do_facet mds1 $LCTL get_param -n \
20193                                                 lod.$mdtname.dom_stripesize)
20194         [ 30000 -eq ${dom_current} ] &&
20195                 error "Can set too small DoM stripe limit"
20196
20197         # 64K is a minimal stripe size in Lustre, expect limit of that size
20198         [ 65536 -eq ${dom_current} ] ||
20199                 error "Limit is not set to 64K but ${dom_current}"
20200
20201         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20202         dom_current=$(do_facet mds1 $LCTL get_param -n \
20203                                                 lod.$mdtname.dom_stripesize)
20204         echo $dom_current
20205         [ 2147483648 -eq ${dom_current} ] &&
20206                 error "Can set too large DoM stripe limit"
20207
20208         do_facet mds1 $LCTL set_param -n \
20209                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20210         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20211                 error "Can't create DoM component size after limit change"
20212         do_facet mds1 $LCTL set_param -n \
20213                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20214         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20215                 error "Can't create DoM file after limit decrease"
20216         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20217                 error "Can create big DoM component after limit decrease"
20218         touch ${dom}_def ||
20219                 error "Can't create file with old default layout"
20220
20221         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20222         return 0
20223 }
20224 run_test 270f "DoM: maximum DoM stripe size checks"
20225
20226 test_270g() {
20227         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20228                 skip "Need MDS version at least 2.13.52"
20229         local dom=$DIR/$tdir/$tfile
20230
20231         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20232         local lodname=${FSNAME}-MDT0000-mdtlov
20233
20234         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20235         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20236         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20237         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20238
20239         local dom_limit=1024
20240         local dom_threshold="50%"
20241
20242         $LFS setstripe -d $DIR/$tdir
20243         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20244                 error "Can't set directory default striping"
20245
20246         do_facet mds1 $LCTL set_param -n \
20247                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20248         # set 0 threshold and create DOM file to change tunable stripesize
20249         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20250         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20251                 error "Failed to create $dom file"
20252         # now tunable dom_cur_stripesize should reach maximum
20253         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20254                                         lod.${lodname}.dom_stripesize_cur_kb)
20255         [[ $dom_current == $dom_limit ]] ||
20256                 error "Current DOM stripesize is not maximum"
20257         rm $dom
20258
20259         # set threshold for further tests
20260         do_facet mds1 $LCTL set_param -n \
20261                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20262         echo "DOM threshold is $dom_threshold free space"
20263         local dom_def
20264         local dom_set
20265         # Spoof bfree to exceed threshold
20266         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20267         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20268         for spfree in 40 20 0 15 30 55; do
20269                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20270                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20271                         error "Failed to create $dom file"
20272                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20273                                         lod.${lodname}.dom_stripesize_cur_kb)
20274                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20275                 [[ $dom_def != $dom_current ]] ||
20276                         error "Default stripe size was not changed"
20277                 if [[ $spfree > 0 ]] ; then
20278                         dom_set=$($LFS getstripe -S $dom)
20279                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20280                                 error "DOM component size is still old"
20281                 else
20282                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20283                                 error "DoM component is set with no free space"
20284                 fi
20285                 rm $dom
20286                 dom_current=$dom_def
20287         done
20288 }
20289 run_test 270g "DoM: default DoM stripe size depends on free space"
20290
20291 test_270h() {
20292         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20293                 skip "Need MDS version at least 2.13.53"
20294
20295         local mdtname=${FSNAME}-MDT0000-mdtlov
20296         local dom=$DIR/$tdir/$tfile
20297         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20298
20299         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20300         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20301
20302         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20303         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20304                 error "can't create OST file"
20305         # mirrored file with DOM entry in the second mirror
20306         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20307                 error "can't create mirror with DoM component"
20308
20309         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20310
20311         # DOM component in the middle and has other enries in the same mirror,
20312         # should succeed but lost DoM component
20313         $LFS setstripe --copy=${dom}_1 $dom ||
20314                 error "Can't create file from OST|DOM mirror layout"
20315         # check new file has no DoM layout after all
20316         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20317                 error "File has DoM component while DoM is disabled"
20318 }
20319 run_test 270h "DoM: DoM stripe removal when disabled on server"
20320
20321 test_271a() {
20322         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20323                 skip "Need MDS version at least 2.10.55"
20324
20325         local dom=$DIR/$tdir/dom
20326
20327         mkdir -p $DIR/$tdir
20328
20329         $LFS setstripe -E 1024K -L mdt $dom
20330
20331         lctl set_param -n mdc.*.stats=clear
20332         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20333         cat $dom > /dev/null
20334         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20335         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20336         ls $dom
20337         rm -f $dom
20338 }
20339 run_test 271a "DoM: data is cached for read after write"
20340
20341 test_271b() {
20342         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20343                 skip "Need MDS version at least 2.10.55"
20344
20345         local dom=$DIR/$tdir/dom
20346
20347         mkdir -p $DIR/$tdir
20348
20349         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20350
20351         lctl set_param -n mdc.*.stats=clear
20352         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20353         cancel_lru_locks mdc
20354         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20355         # second stat to check size is cached on client
20356         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20357         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20358         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20359         rm -f $dom
20360 }
20361 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20362
20363 test_271ba() {
20364         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20365                 skip "Need MDS version at least 2.10.55"
20366
20367         local dom=$DIR/$tdir/dom
20368
20369         mkdir -p $DIR/$tdir
20370
20371         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20372
20373         lctl set_param -n mdc.*.stats=clear
20374         lctl set_param -n osc.*.stats=clear
20375         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20376         cancel_lru_locks mdc
20377         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20378         # second stat to check size is cached on client
20379         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20380         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20381         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20382         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20383         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20384         rm -f $dom
20385 }
20386 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20387
20388
20389 get_mdc_stats() {
20390         local mdtidx=$1
20391         local param=$2
20392         local mdt=MDT$(printf %04x $mdtidx)
20393
20394         if [ -z $param ]; then
20395                 lctl get_param -n mdc.*$mdt*.stats
20396         else
20397                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20398         fi
20399 }
20400
20401 test_271c() {
20402         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20403                 skip "Need MDS version at least 2.10.55"
20404
20405         local dom=$DIR/$tdir/dom
20406
20407         mkdir -p $DIR/$tdir
20408
20409         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20410
20411         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20412         local facet=mds$((mdtidx + 1))
20413
20414         cancel_lru_locks mdc
20415         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20416         createmany -o $dom 1000
20417         lctl set_param -n mdc.*.stats=clear
20418         smalliomany -w $dom 1000 200
20419         get_mdc_stats $mdtidx
20420         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20421         # Each file has 1 open, 1 IO enqueues, total 2000
20422         # but now we have also +1 getxattr for security.capability, total 3000
20423         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20424         unlinkmany $dom 1000
20425
20426         cancel_lru_locks mdc
20427         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20428         createmany -o $dom 1000
20429         lctl set_param -n mdc.*.stats=clear
20430         smalliomany -w $dom 1000 200
20431         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20432         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20433         # for OPEN and IO lock.
20434         [ $((enq - enq_2)) -ge 1000 ] ||
20435                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20436         unlinkmany $dom 1000
20437         return 0
20438 }
20439 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20440
20441 cleanup_271def_tests() {
20442         trap 0
20443         rm -f $1
20444 }
20445
20446 test_271d() {
20447         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20448                 skip "Need MDS version at least 2.10.57"
20449
20450         local dom=$DIR/$tdir/dom
20451         local tmp=$TMP/$tfile
20452         trap "cleanup_271def_tests $tmp" EXIT
20453
20454         mkdir -p $DIR/$tdir
20455
20456         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20457
20458         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20459
20460         cancel_lru_locks mdc
20461         dd if=/dev/urandom of=$tmp bs=1000 count=1
20462         dd if=$tmp of=$dom bs=1000 count=1
20463         cancel_lru_locks mdc
20464
20465         cat /etc/hosts >> $tmp
20466         lctl set_param -n mdc.*.stats=clear
20467
20468         # append data to the same file it should update local page
20469         echo "Append to the same page"
20470         cat /etc/hosts >> $dom
20471         local num=$(get_mdc_stats $mdtidx ost_read)
20472         local ra=$(get_mdc_stats $mdtidx req_active)
20473         local rw=$(get_mdc_stats $mdtidx req_waittime)
20474
20475         [ -z $num ] || error "$num READ RPC occured"
20476         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20477         echo "... DONE"
20478
20479         # compare content
20480         cmp $tmp $dom || error "file miscompare"
20481
20482         cancel_lru_locks mdc
20483         lctl set_param -n mdc.*.stats=clear
20484
20485         echo "Open and read file"
20486         cat $dom > /dev/null
20487         local num=$(get_mdc_stats $mdtidx ost_read)
20488         local ra=$(get_mdc_stats $mdtidx req_active)
20489         local rw=$(get_mdc_stats $mdtidx req_waittime)
20490
20491         [ -z $num ] || error "$num READ RPC occured"
20492         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20493         echo "... DONE"
20494
20495         # compare content
20496         cmp $tmp $dom || error "file miscompare"
20497
20498         return 0
20499 }
20500 run_test 271d "DoM: read on open (1K file in reply buffer)"
20501
20502 test_271f() {
20503         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20504                 skip "Need MDS version at least 2.10.57"
20505
20506         local dom=$DIR/$tdir/dom
20507         local tmp=$TMP/$tfile
20508         trap "cleanup_271def_tests $tmp" EXIT
20509
20510         mkdir -p $DIR/$tdir
20511
20512         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20513
20514         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20515
20516         cancel_lru_locks mdc
20517         dd if=/dev/urandom of=$tmp bs=265000 count=1
20518         dd if=$tmp of=$dom bs=265000 count=1
20519         cancel_lru_locks mdc
20520         cat /etc/hosts >> $tmp
20521         lctl set_param -n mdc.*.stats=clear
20522
20523         echo "Append to the same page"
20524         cat /etc/hosts >> $dom
20525         local num=$(get_mdc_stats $mdtidx ost_read)
20526         local ra=$(get_mdc_stats $mdtidx req_active)
20527         local rw=$(get_mdc_stats $mdtidx req_waittime)
20528
20529         [ -z $num ] || error "$num READ RPC occured"
20530         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20531         echo "... DONE"
20532
20533         # compare content
20534         cmp $tmp $dom || error "file miscompare"
20535
20536         cancel_lru_locks mdc
20537         lctl set_param -n mdc.*.stats=clear
20538
20539         echo "Open and read file"
20540         cat $dom > /dev/null
20541         local num=$(get_mdc_stats $mdtidx ost_read)
20542         local ra=$(get_mdc_stats $mdtidx req_active)
20543         local rw=$(get_mdc_stats $mdtidx req_waittime)
20544
20545         [ -z $num ] && num=0
20546         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20547         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20548         echo "... DONE"
20549
20550         # compare content
20551         cmp $tmp $dom || error "file miscompare"
20552
20553         return 0
20554 }
20555 run_test 271f "DoM: read on open (200K file and read tail)"
20556
20557 test_271g() {
20558         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20559                 skip "Skipping due to old client or server version"
20560
20561         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20562         # to get layout
20563         $CHECKSTAT -t file $DIR1/$tfile
20564
20565         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20566         MULTIOP_PID=$!
20567         sleep 1
20568         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20569         $LCTL set_param fail_loc=0x80000314
20570         rm $DIR1/$tfile || error "Unlink fails"
20571         RC=$?
20572         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20573         [ $RC -eq 0 ] || error "Failed write to stale object"
20574 }
20575 run_test 271g "Discard DoM data vs client flush race"
20576
20577 test_272a() {
20578         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20579                 skip "Need MDS version at least 2.11.50"
20580
20581         local dom=$DIR/$tdir/dom
20582         mkdir -p $DIR/$tdir
20583
20584         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20585         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20586                 error "failed to write data into $dom"
20587         local old_md5=$(md5sum $dom)
20588
20589         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20590                 error "failed to migrate to the same DoM component"
20591
20592         local new_md5=$(md5sum $dom)
20593
20594         [ "$old_md5" == "$new_md5" ] ||
20595                 error "md5sum differ: $old_md5, $new_md5"
20596
20597         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20598                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20599 }
20600 run_test 272a "DoM migration: new layout with the same DOM component"
20601
20602 test_272b() {
20603         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20604                 skip "Need MDS version at least 2.11.50"
20605
20606         local dom=$DIR/$tdir/dom
20607         mkdir -p $DIR/$tdir
20608         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20609
20610         local mdtidx=$($LFS getstripe -m $dom)
20611         local mdtname=MDT$(printf %04x $mdtidx)
20612         local facet=mds$((mdtidx + 1))
20613
20614         local mdtfree1=$(do_facet $facet \
20615                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20616         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20617                 error "failed to write data into $dom"
20618         local old_md5=$(md5sum $dom)
20619         cancel_lru_locks mdc
20620         local mdtfree1=$(do_facet $facet \
20621                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20622
20623         $LFS migrate -c2 $dom ||
20624                 error "failed to migrate to the new composite layout"
20625         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20626                 error "MDT stripe was not removed"
20627
20628         cancel_lru_locks mdc
20629         local new_md5=$(md5sum $dom)
20630         [ "$old_md5" == "$new_md5" ] ||
20631                 error "$old_md5 != $new_md5"
20632
20633         # Skip free space checks with ZFS
20634         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20635                 local mdtfree2=$(do_facet $facet \
20636                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20637                 [ $mdtfree2 -gt $mdtfree1 ] ||
20638                         error "MDT space is not freed after migration"
20639         fi
20640         return 0
20641 }
20642 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20643
20644 test_272c() {
20645         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20646                 skip "Need MDS version at least 2.11.50"
20647
20648         local dom=$DIR/$tdir/$tfile
20649         mkdir -p $DIR/$tdir
20650         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20651
20652         local mdtidx=$($LFS getstripe -m $dom)
20653         local mdtname=MDT$(printf %04x $mdtidx)
20654         local facet=mds$((mdtidx + 1))
20655
20656         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20657                 error "failed to write data into $dom"
20658         local old_md5=$(md5sum $dom)
20659         cancel_lru_locks mdc
20660         local mdtfree1=$(do_facet $facet \
20661                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20662
20663         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20664                 error "failed to migrate to the new composite layout"
20665         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20666                 error "MDT stripe was not removed"
20667
20668         cancel_lru_locks mdc
20669         local new_md5=$(md5sum $dom)
20670         [ "$old_md5" == "$new_md5" ] ||
20671                 error "$old_md5 != $new_md5"
20672
20673         # Skip free space checks with ZFS
20674         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20675                 local mdtfree2=$(do_facet $facet \
20676                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20677                 [ $mdtfree2 -gt $mdtfree1 ] ||
20678                         error "MDS space is not freed after migration"
20679         fi
20680         return 0
20681 }
20682 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20683
20684 test_272d() {
20685         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20686                 skip "Need MDS version at least 2.12.55"
20687
20688         local dom=$DIR/$tdir/$tfile
20689         mkdir -p $DIR/$tdir
20690         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20691
20692         local mdtidx=$($LFS getstripe -m $dom)
20693         local mdtname=MDT$(printf %04x $mdtidx)
20694         local facet=mds$((mdtidx + 1))
20695
20696         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20697                 error "failed to write data into $dom"
20698         local old_md5=$(md5sum $dom)
20699         cancel_lru_locks mdc
20700         local mdtfree1=$(do_facet $facet \
20701                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20702
20703         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20704                 error "failed mirroring to the new composite layout"
20705         $LFS mirror resync $dom ||
20706                 error "failed mirror resync"
20707         $LFS mirror split --mirror-id 1 -d $dom ||
20708                 error "failed mirror split"
20709
20710         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20711                 error "MDT stripe was not removed"
20712
20713         cancel_lru_locks mdc
20714         local new_md5=$(md5sum $dom)
20715         [ "$old_md5" == "$new_md5" ] ||
20716                 error "$old_md5 != $new_md5"
20717
20718         # Skip free space checks with ZFS
20719         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20720                 local mdtfree2=$(do_facet $facet \
20721                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20722                 [ $mdtfree2 -gt $mdtfree1 ] ||
20723                         error "MDS space is not freed after DOM mirror deletion"
20724         fi
20725         return 0
20726 }
20727 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20728
20729 test_272e() {
20730         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20731                 skip "Need MDS version at least 2.12.55"
20732
20733         local dom=$DIR/$tdir/$tfile
20734         mkdir -p $DIR/$tdir
20735         $LFS setstripe -c 2 $dom
20736
20737         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20738                 error "failed to write data into $dom"
20739         local old_md5=$(md5sum $dom)
20740         cancel_lru_locks mdc
20741
20742         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20743                 error "failed mirroring to the DOM layout"
20744         $LFS mirror resync $dom ||
20745                 error "failed mirror resync"
20746         $LFS mirror split --mirror-id 1 -d $dom ||
20747                 error "failed mirror split"
20748
20749         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20750                 error "MDT stripe was not removed"
20751
20752         cancel_lru_locks mdc
20753         local new_md5=$(md5sum $dom)
20754         [ "$old_md5" == "$new_md5" ] ||
20755                 error "$old_md5 != $new_md5"
20756
20757         return 0
20758 }
20759 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20760
20761 test_272f() {
20762         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20763                 skip "Need MDS version at least 2.12.55"
20764
20765         local dom=$DIR/$tdir/$tfile
20766         mkdir -p $DIR/$tdir
20767         $LFS setstripe -c 2 $dom
20768
20769         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20770                 error "failed to write data into $dom"
20771         local old_md5=$(md5sum $dom)
20772         cancel_lru_locks mdc
20773
20774         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20775                 error "failed migrating to the DOM file"
20776
20777         cancel_lru_locks mdc
20778         local new_md5=$(md5sum $dom)
20779         [ "$old_md5" != "$new_md5" ] &&
20780                 error "$old_md5 != $new_md5"
20781
20782         return 0
20783 }
20784 run_test 272f "DoM migration: OST-striped file to DOM file"
20785
20786 test_273a() {
20787         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20788                 skip "Need MDS version at least 2.11.50"
20789
20790         # Layout swap cannot be done if either file has DOM component,
20791         # this will never be supported, migration should be used instead
20792
20793         local dom=$DIR/$tdir/$tfile
20794         mkdir -p $DIR/$tdir
20795
20796         $LFS setstripe -c2 ${dom}_plain
20797         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20798         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20799                 error "can swap layout with DoM component"
20800         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20801                 error "can swap layout with DoM component"
20802
20803         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20804         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20805                 error "can swap layout with DoM component"
20806         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20807                 error "can swap layout with DoM component"
20808         return 0
20809 }
20810 run_test 273a "DoM: layout swapping should fail with DOM"
20811
20812 test_275() {
20813         remote_ost_nodsh && skip "remote OST with nodsh"
20814         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20815                 skip "Need OST version >= 2.10.57"
20816
20817         local file=$DIR/$tfile
20818         local oss
20819
20820         oss=$(comma_list $(osts_nodes))
20821
20822         dd if=/dev/urandom of=$file bs=1M count=2 ||
20823                 error "failed to create a file"
20824         cancel_lru_locks osc
20825
20826         #lock 1
20827         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20828                 error "failed to read a file"
20829
20830 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20831         $LCTL set_param fail_loc=0x8000031f
20832
20833         cancel_lru_locks osc &
20834         sleep 1
20835
20836 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20837         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20838         #IO takes another lock, but matches the PENDING one
20839         #and places it to the IO RPC
20840         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20841                 error "failed to read a file with PENDING lock"
20842 }
20843 run_test 275 "Read on a canceled duplicate lock"
20844
20845 test_276() {
20846         remote_ost_nodsh && skip "remote OST with nodsh"
20847         local pid
20848
20849         do_facet ost1 "(while true; do \
20850                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20851                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20852         pid=$!
20853
20854         for LOOP in $(seq 20); do
20855                 stop ost1
20856                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20857         done
20858         kill -9 $pid
20859         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20860                 rm $TMP/sanity_276_pid"
20861 }
20862 run_test 276 "Race between mount and obd_statfs"
20863
20864 test_277() {
20865         $LCTL set_param ldlm.namespaces.*.lru_size=0
20866         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20867         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20868                         grep ^used_mb | awk '{print $2}')
20869         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20870         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20871                 oflag=direct conv=notrunc
20872         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20873                         grep ^used_mb | awk '{print $2}')
20874         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20875 }
20876 run_test 277 "Direct IO shall drop page cache"
20877
20878 test_278() {
20879         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20880         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20881         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20882                 skip "needs the same host for mdt1 mdt2" && return
20883
20884         local pid1
20885         local pid2
20886
20887 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20888         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20889         stop mds2 &
20890         pid2=$!
20891
20892         stop mds1
20893
20894         echo "Starting MDTs"
20895         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20896         wait $pid2
20897 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20898 #will return NULL
20899         do_facet mds2 $LCTL set_param fail_loc=0
20900
20901         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20902         wait_recovery_complete mds2
20903 }
20904 run_test 278 "Race starting MDS between MDTs stop/start"
20905
20906 test_280() {
20907         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20908                 skip "Need MGS version at least 2.13.52"
20909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20910         combined_mgs_mds || skip "needs combined MGS/MDT"
20911
20912         umount_client $MOUNT
20913 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20914         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20915
20916         mount_client $MOUNT &
20917         sleep 1
20918         stop mgs || error "stop mgs failed"
20919         #for a race mgs would crash
20920         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20921         mount_client $MOUNT || error "mount client failed"
20922 }
20923 run_test 280 "Race between MGS umount and client llog processing"
20924
20925 cleanup_test_300() {
20926         trap 0
20927         umask $SAVE_UMASK
20928 }
20929 test_striped_dir() {
20930         local mdt_index=$1
20931         local stripe_count
20932         local stripe_index
20933
20934         mkdir -p $DIR/$tdir
20935
20936         SAVE_UMASK=$(umask)
20937         trap cleanup_test_300 RETURN EXIT
20938
20939         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20940                                                 $DIR/$tdir/striped_dir ||
20941                 error "set striped dir error"
20942
20943         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20944         [ "$mode" = "755" ] || error "expect 755 got $mode"
20945
20946         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20947                 error "getdirstripe failed"
20948         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20949         if [ "$stripe_count" != "2" ]; then
20950                 error "1:stripe_count is $stripe_count, expect 2"
20951         fi
20952         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20953         if [ "$stripe_count" != "2" ]; then
20954                 error "2:stripe_count is $stripe_count, expect 2"
20955         fi
20956
20957         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20958         if [ "$stripe_index" != "$mdt_index" ]; then
20959                 error "stripe_index is $stripe_index, expect $mdt_index"
20960         fi
20961
20962         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20963                 error "nlink error after create striped dir"
20964
20965         mkdir $DIR/$tdir/striped_dir/a
20966         mkdir $DIR/$tdir/striped_dir/b
20967
20968         stat $DIR/$tdir/striped_dir/a ||
20969                 error "create dir under striped dir failed"
20970         stat $DIR/$tdir/striped_dir/b ||
20971                 error "create dir under striped dir failed"
20972
20973         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20974                 error "nlink error after mkdir"
20975
20976         rmdir $DIR/$tdir/striped_dir/a
20977         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20978                 error "nlink error after rmdir"
20979
20980         rmdir $DIR/$tdir/striped_dir/b
20981         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20982                 error "nlink error after rmdir"
20983
20984         chattr +i $DIR/$tdir/striped_dir
20985         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20986                 error "immutable flags not working under striped dir!"
20987         chattr -i $DIR/$tdir/striped_dir
20988
20989         rmdir $DIR/$tdir/striped_dir ||
20990                 error "rmdir striped dir error"
20991
20992         cleanup_test_300
20993
20994         true
20995 }
20996
20997 test_300a() {
20998         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20999                 skip "skipped for lustre < 2.7.0"
21000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21001         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21002
21003         test_striped_dir 0 || error "failed on striped dir on MDT0"
21004         test_striped_dir 1 || error "failed on striped dir on MDT0"
21005 }
21006 run_test 300a "basic striped dir sanity test"
21007
21008 test_300b() {
21009         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21010                 skip "skipped for lustre < 2.7.0"
21011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21012         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21013
21014         local i
21015         local mtime1
21016         local mtime2
21017         local mtime3
21018
21019         test_mkdir $DIR/$tdir || error "mkdir fail"
21020         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21021                 error "set striped dir error"
21022         for i in {0..9}; do
21023                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21024                 sleep 1
21025                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21026                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21027                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21028                 sleep 1
21029                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21030                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21031                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21032         done
21033         true
21034 }
21035 run_test 300b "check ctime/mtime for striped dir"
21036
21037 test_300c() {
21038         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21039                 skip "skipped for lustre < 2.7.0"
21040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21041         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21042
21043         local file_count
21044
21045         mkdir -p $DIR/$tdir
21046         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21047                 error "set striped dir error"
21048
21049         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21050                 error "chown striped dir failed"
21051
21052         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21053                 error "create 5k files failed"
21054
21055         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21056
21057         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21058
21059         rm -rf $DIR/$tdir
21060 }
21061 run_test 300c "chown && check ls under striped directory"
21062
21063 test_300d() {
21064         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21065                 skip "skipped for lustre < 2.7.0"
21066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21068
21069         local stripe_count
21070         local file
21071
21072         mkdir -p $DIR/$tdir
21073         $LFS setstripe -c 2 $DIR/$tdir
21074
21075         #local striped directory
21076         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21077                 error "set striped dir error"
21078         #look at the directories for debug purposes
21079         ls -l $DIR/$tdir
21080         $LFS getdirstripe $DIR/$tdir
21081         ls -l $DIR/$tdir/striped_dir
21082         $LFS getdirstripe $DIR/$tdir/striped_dir
21083         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21084                 error "create 10 files failed"
21085
21086         #remote striped directory
21087         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21088                 error "set striped dir error"
21089         #look at the directories for debug purposes
21090         ls -l $DIR/$tdir
21091         $LFS getdirstripe $DIR/$tdir
21092         ls -l $DIR/$tdir/remote_striped_dir
21093         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21094         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21095                 error "create 10 files failed"
21096
21097         for file in $(find $DIR/$tdir); do
21098                 stripe_count=$($LFS getstripe -c $file)
21099                 [ $stripe_count -eq 2 ] ||
21100                         error "wrong stripe $stripe_count for $file"
21101         done
21102
21103         rm -rf $DIR/$tdir
21104 }
21105 run_test 300d "check default stripe under striped directory"
21106
21107 test_300e() {
21108         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21109                 skip "Need MDS version at least 2.7.55"
21110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21111         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21112
21113         local stripe_count
21114         local file
21115
21116         mkdir -p $DIR/$tdir
21117
21118         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21119                 error "set striped dir error"
21120
21121         touch $DIR/$tdir/striped_dir/a
21122         touch $DIR/$tdir/striped_dir/b
21123         touch $DIR/$tdir/striped_dir/c
21124
21125         mkdir $DIR/$tdir/striped_dir/dir_a
21126         mkdir $DIR/$tdir/striped_dir/dir_b
21127         mkdir $DIR/$tdir/striped_dir/dir_c
21128
21129         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21130                 error "set striped adir under striped dir error"
21131
21132         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21133                 error "set striped bdir under striped dir error"
21134
21135         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21136                 error "set striped cdir under striped dir error"
21137
21138         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21139                 error "rename dir under striped dir fails"
21140
21141         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21142                 error "rename dir under different stripes fails"
21143
21144         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21145                 error "rename file under striped dir should succeed"
21146
21147         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21148                 error "rename dir under striped dir should succeed"
21149
21150         rm -rf $DIR/$tdir
21151 }
21152 run_test 300e "check rename under striped directory"
21153
21154 test_300f() {
21155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21156         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21157         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21158                 skip "Need MDS version at least 2.7.55"
21159
21160         local stripe_count
21161         local file
21162
21163         rm -rf $DIR/$tdir
21164         mkdir -p $DIR/$tdir
21165
21166         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21167                 error "set striped dir error"
21168
21169         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21170                 error "set striped dir error"
21171
21172         touch $DIR/$tdir/striped_dir/a
21173         mkdir $DIR/$tdir/striped_dir/dir_a
21174         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21175                 error "create striped dir under striped dir fails"
21176
21177         touch $DIR/$tdir/striped_dir1/b
21178         mkdir $DIR/$tdir/striped_dir1/dir_b
21179         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21180                 error "create striped dir under striped dir fails"
21181
21182         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21183                 error "rename dir under different striped dir should fail"
21184
21185         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21186                 error "rename striped dir under diff striped dir should fail"
21187
21188         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21189                 error "rename file under diff striped dirs fails"
21190
21191         rm -rf $DIR/$tdir
21192 }
21193 run_test 300f "check rename cross striped directory"
21194
21195 test_300_check_default_striped_dir()
21196 {
21197         local dirname=$1
21198         local default_count=$2
21199         local default_index=$3
21200         local stripe_count
21201         local stripe_index
21202         local dir_stripe_index
21203         local dir
21204
21205         echo "checking $dirname $default_count $default_index"
21206         $LFS setdirstripe -D -c $default_count -i $default_index \
21207                                 -t all_char $DIR/$tdir/$dirname ||
21208                 error "set default stripe on striped dir error"
21209         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21210         [ $stripe_count -eq $default_count ] ||
21211                 error "expect $default_count get $stripe_count for $dirname"
21212
21213         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21214         [ $stripe_index -eq $default_index ] ||
21215                 error "expect $default_index get $stripe_index for $dirname"
21216
21217         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21218                                                 error "create dirs failed"
21219
21220         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21221         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21222         for dir in $(find $DIR/$tdir/$dirname/*); do
21223                 stripe_count=$($LFS getdirstripe -c $dir)
21224                 [ $stripe_count -eq $default_count ] ||
21225                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21226                 error "stripe count $default_count != $stripe_count for $dir"
21227
21228                 stripe_index=$($LFS getdirstripe -i $dir)
21229                 [ $default_index -eq -1 ] ||
21230                         [ $stripe_index -eq $default_index ] ||
21231                         error "$stripe_index != $default_index for $dir"
21232
21233                 #check default stripe
21234                 stripe_count=$($LFS getdirstripe -D -c $dir)
21235                 [ $stripe_count -eq $default_count ] ||
21236                 error "default count $default_count != $stripe_count for $dir"
21237
21238                 stripe_index=$($LFS getdirstripe -D -i $dir)
21239                 [ $stripe_index -eq $default_index ] ||
21240                 error "default index $default_index != $stripe_index for $dir"
21241         done
21242         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21243 }
21244
21245 test_300g() {
21246         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21247         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21248                 skip "Need MDS version at least 2.7.55"
21249
21250         local dir
21251         local stripe_count
21252         local stripe_index
21253
21254         mkdir $DIR/$tdir
21255         mkdir $DIR/$tdir/normal_dir
21256
21257         #Checking when client cache stripe index
21258         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21259         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21260                 error "create striped_dir failed"
21261
21262         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21263                 error "create dir0 fails"
21264         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21265         [ $stripe_index -eq 0 ] ||
21266                 error "dir0 expect index 0 got $stripe_index"
21267
21268         mkdir $DIR/$tdir/striped_dir/dir1 ||
21269                 error "create dir1 fails"
21270         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21271         [ $stripe_index -eq 1 ] ||
21272                 error "dir1 expect index 1 got $stripe_index"
21273
21274         #check default stripe count/stripe index
21275         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21276         test_300_check_default_striped_dir normal_dir 1 0
21277         test_300_check_default_striped_dir normal_dir 2 1
21278         test_300_check_default_striped_dir normal_dir 2 -1
21279
21280         #delete default stripe information
21281         echo "delete default stripeEA"
21282         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21283                 error "set default stripe on striped dir error"
21284
21285         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21286         for dir in $(find $DIR/$tdir/normal_dir/*); do
21287                 stripe_count=$($LFS getdirstripe -c $dir)
21288                 [ $stripe_count -eq 0 ] ||
21289                         error "expect 1 get $stripe_count for $dir"
21290                 stripe_index=$($LFS getdirstripe -i $dir)
21291                 [ $stripe_index -eq 0 ] ||
21292                         error "expect 0 get $stripe_index for $dir"
21293         done
21294 }
21295 run_test 300g "check default striped directory for normal directory"
21296
21297 test_300h() {
21298         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21299         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21300                 skip "Need MDS version at least 2.7.55"
21301
21302         local dir
21303         local stripe_count
21304
21305         mkdir $DIR/$tdir
21306         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21307                 error "set striped dir error"
21308
21309         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21310         test_300_check_default_striped_dir striped_dir 1 0
21311         test_300_check_default_striped_dir striped_dir 2 1
21312         test_300_check_default_striped_dir striped_dir 2 -1
21313
21314         #delete default stripe information
21315         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21316                 error "set default stripe on striped dir error"
21317
21318         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21319         for dir in $(find $DIR/$tdir/striped_dir/*); do
21320                 stripe_count=$($LFS getdirstripe -c $dir)
21321                 [ $stripe_count -eq 0 ] ||
21322                         error "expect 1 get $stripe_count for $dir"
21323         done
21324 }
21325 run_test 300h "check default striped directory for striped directory"
21326
21327 test_300i() {
21328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21329         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21330         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21331                 skip "Need MDS version at least 2.7.55"
21332
21333         local stripe_count
21334         local file
21335
21336         mkdir $DIR/$tdir
21337
21338         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21339                 error "set striped dir error"
21340
21341         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21342                 error "create files under striped dir failed"
21343
21344         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21345                 error "set striped hashdir error"
21346
21347         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21348                 error "create dir0 under hash dir failed"
21349         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21350                 error "create dir1 under hash dir failed"
21351
21352         # unfortunately, we need to umount to clear dir layout cache for now
21353         # once we fully implement dir layout, we can drop this
21354         umount_client $MOUNT || error "umount failed"
21355         mount_client $MOUNT || error "mount failed"
21356
21357         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21358         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21359         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21360
21361         #set the stripe to be unknown hash type
21362         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21363         $LCTL set_param fail_loc=0x1901
21364         for ((i = 0; i < 10; i++)); do
21365                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21366                         error "stat f-$i failed"
21367                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21368         done
21369
21370         touch $DIR/$tdir/striped_dir/f0 &&
21371                 error "create under striped dir with unknown hash should fail"
21372
21373         $LCTL set_param fail_loc=0
21374
21375         umount_client $MOUNT || error "umount failed"
21376         mount_client $MOUNT || error "mount failed"
21377
21378         return 0
21379 }
21380 run_test 300i "client handle unknown hash type striped directory"
21381
21382 test_300j() {
21383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21385         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21386                 skip "Need MDS version at least 2.7.55"
21387
21388         local stripe_count
21389         local file
21390
21391         mkdir $DIR/$tdir
21392
21393         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21394         $LCTL set_param fail_loc=0x1702
21395         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21396                 error "set striped dir error"
21397
21398         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21399                 error "create files under striped dir failed"
21400
21401         $LCTL set_param fail_loc=0
21402
21403         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21404
21405         return 0
21406 }
21407 run_test 300j "test large update record"
21408
21409 test_300k() {
21410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21411         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21412         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21413                 skip "Need MDS version at least 2.7.55"
21414
21415         # this test needs a huge transaction
21416         local kb
21417         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21418              osd*.$FSNAME-MDT0000.kbytestotal")
21419         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21420
21421         local stripe_count
21422         local file
21423
21424         mkdir $DIR/$tdir
21425
21426         #define OBD_FAIL_LARGE_STRIPE   0x1703
21427         $LCTL set_param fail_loc=0x1703
21428         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21429                 error "set striped dir error"
21430         $LCTL set_param fail_loc=0
21431
21432         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21433                 error "getstripeddir fails"
21434         rm -rf $DIR/$tdir/striped_dir ||
21435                 error "unlink striped dir fails"
21436
21437         return 0
21438 }
21439 run_test 300k "test large striped directory"
21440
21441 test_300l() {
21442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21444         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21445                 skip "Need MDS version at least 2.7.55"
21446
21447         local stripe_index
21448
21449         test_mkdir -p $DIR/$tdir/striped_dir
21450         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21451                         error "chown $RUNAS_ID failed"
21452         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21453                 error "set default striped dir failed"
21454
21455         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21456         $LCTL set_param fail_loc=0x80000158
21457         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21458
21459         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21460         [ $stripe_index -eq 1 ] ||
21461                 error "expect 1 get $stripe_index for $dir"
21462 }
21463 run_test 300l "non-root user to create dir under striped dir with stale layout"
21464
21465 test_300m() {
21466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21467         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21468         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21469                 skip "Need MDS version at least 2.7.55"
21470
21471         mkdir -p $DIR/$tdir/striped_dir
21472         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21473                 error "set default stripes dir error"
21474
21475         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21476
21477         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21478         [ $stripe_count -eq 0 ] ||
21479                         error "expect 0 get $stripe_count for a"
21480
21481         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21482                 error "set default stripes dir error"
21483
21484         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21485
21486         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21487         [ $stripe_count -eq 0 ] ||
21488                         error "expect 0 get $stripe_count for b"
21489
21490         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21491                 error "set default stripes dir error"
21492
21493         mkdir $DIR/$tdir/striped_dir/c &&
21494                 error "default stripe_index is invalid, mkdir c should fails"
21495
21496         rm -rf $DIR/$tdir || error "rmdir fails"
21497 }
21498 run_test 300m "setstriped directory on single MDT FS"
21499
21500 cleanup_300n() {
21501         local list=$(comma_list $(mdts_nodes))
21502
21503         trap 0
21504         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21505 }
21506
21507 test_300n() {
21508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21509         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21510         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21511                 skip "Need MDS version at least 2.7.55"
21512         remote_mds_nodsh && skip "remote MDS with nodsh"
21513
21514         local stripe_index
21515         local list=$(comma_list $(mdts_nodes))
21516
21517         trap cleanup_300n RETURN EXIT
21518         mkdir -p $DIR/$tdir
21519         chmod 777 $DIR/$tdir
21520         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21521                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21522                 error "create striped dir succeeds with gid=0"
21523
21524         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21525         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21526                 error "create striped dir fails with gid=-1"
21527
21528         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21529         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21530                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21531                 error "set default striped dir succeeds with gid=0"
21532
21533
21534         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21535         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21536                 error "set default striped dir fails with gid=-1"
21537
21538
21539         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21540         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21541                                         error "create test_dir fails"
21542         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21543                                         error "create test_dir1 fails"
21544         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21545                                         error "create test_dir2 fails"
21546         cleanup_300n
21547 }
21548 run_test 300n "non-root user to create dir under striped dir with default EA"
21549
21550 test_300o() {
21551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21552         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21553         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21554                 skip "Need MDS version at least 2.7.55"
21555
21556         local numfree1
21557         local numfree2
21558
21559         mkdir -p $DIR/$tdir
21560
21561         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21562         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21563         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21564                 skip "not enough free inodes $numfree1 $numfree2"
21565         fi
21566
21567         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21568         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21569         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21570                 skip "not enough free space $numfree1 $numfree2"
21571         fi
21572
21573         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21574                 error "setdirstripe fails"
21575
21576         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21577                 error "create dirs fails"
21578
21579         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21580         ls $DIR/$tdir/striped_dir > /dev/null ||
21581                 error "ls striped dir fails"
21582         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21583                 error "unlink big striped dir fails"
21584 }
21585 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21586
21587 test_300p() {
21588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21589         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21590         remote_mds_nodsh && skip "remote MDS with nodsh"
21591
21592         mkdir -p $DIR/$tdir
21593
21594         #define OBD_FAIL_OUT_ENOSPC     0x1704
21595         do_facet mds2 lctl set_param fail_loc=0x80001704
21596         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21597                  && error "create striped directory should fail"
21598
21599         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21600
21601         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21602         true
21603 }
21604 run_test 300p "create striped directory without space"
21605
21606 test_300q() {
21607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21608         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21609
21610         local fd=$(free_fd)
21611         local cmd="exec $fd<$tdir"
21612         cd $DIR
21613         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21614         eval $cmd
21615         cmd="exec $fd<&-"
21616         trap "eval $cmd" EXIT
21617         cd $tdir || error "cd $tdir fails"
21618         rmdir  ../$tdir || error "rmdir $tdir fails"
21619         mkdir local_dir && error "create dir succeeds"
21620         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21621         eval $cmd
21622         return 0
21623 }
21624 run_test 300q "create remote directory under orphan directory"
21625
21626 test_300r() {
21627         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21628                 skip "Need MDS version at least 2.7.55" && return
21629         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21630
21631         mkdir $DIR/$tdir
21632
21633         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21634                 error "set striped dir error"
21635
21636         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21637                 error "getstripeddir fails"
21638
21639         local stripe_count
21640         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21641                       awk '/lmv_stripe_count:/ { print $2 }')
21642
21643         [ $MDSCOUNT -ne $stripe_count ] &&
21644                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21645
21646         rm -rf $DIR/$tdir/striped_dir ||
21647                 error "unlink striped dir fails"
21648 }
21649 run_test 300r "test -1 striped directory"
21650
21651 test_300s_helper() {
21652         local count=$1
21653
21654         local stripe_dir=$DIR/$tdir/striped_dir.$count
21655
21656         $LFS mkdir -c $count $stripe_dir ||
21657                 error "lfs mkdir -c error"
21658
21659         $LFS getdirstripe $stripe_dir ||
21660                 error "lfs getdirstripe fails"
21661
21662         local stripe_count
21663         stripe_count=$($LFS getdirstripe $stripe_dir |
21664                       awk '/lmv_stripe_count:/ { print $2 }')
21665
21666         [ $count -ne $stripe_count ] &&
21667                 error_noexit "bad stripe count $stripe_count expected $count"
21668
21669         local dupe_stripes
21670         dupe_stripes=$($LFS getdirstripe $stripe_dir |
21671                 awk '/0x/ {count[$1] += 1}; END {
21672                         for (idx in count) {
21673                                 if (count[idx]>1) {
21674                                         print "index " idx " count " count[idx]
21675                                 }
21676                         }
21677                 }')
21678
21679         if [[ -n "$dupe_stripes" ]] ; then
21680                 lfs getdirstripe $stripe_dir
21681                 error_noexit "Dupe MDT above: $dupe_stripes "
21682         fi
21683
21684         rm -rf $stripe_dir ||
21685                 error_noexit "unlink $stripe_dir fails"
21686 }
21687
21688 test_300s() {
21689         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21690                 skip "Need MDS version at least 2.7.55" && return
21691         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21692
21693         mkdir $DIR/$tdir
21694         for count in $(seq 2 $MDSCOUNT); do
21695                 test_300s_helper $count
21696         done
21697 }
21698 run_test 300s "test lfs mkdir -c without -i"
21699
21700
21701 prepare_remote_file() {
21702         mkdir $DIR/$tdir/src_dir ||
21703                 error "create remote source failed"
21704
21705         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21706                  error "cp to remote source failed"
21707         touch $DIR/$tdir/src_dir/a
21708
21709         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21710                 error "create remote target dir failed"
21711
21712         touch $DIR/$tdir/tgt_dir/b
21713
21714         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21715                 error "rename dir cross MDT failed!"
21716
21717         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21718                 error "src_child still exists after rename"
21719
21720         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21721                 error "missing file(a) after rename"
21722
21723         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21724                 error "diff after rename"
21725 }
21726
21727 test_310a() {
21728         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21730
21731         local remote_file=$DIR/$tdir/tgt_dir/b
21732
21733         mkdir -p $DIR/$tdir
21734
21735         prepare_remote_file || error "prepare remote file failed"
21736
21737         #open-unlink file
21738         $OPENUNLINK $remote_file $remote_file ||
21739                 error "openunlink $remote_file failed"
21740         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21741 }
21742 run_test 310a "open unlink remote file"
21743
21744 test_310b() {
21745         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21747
21748         local remote_file=$DIR/$tdir/tgt_dir/b
21749
21750         mkdir -p $DIR/$tdir
21751
21752         prepare_remote_file || error "prepare remote file failed"
21753
21754         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21755         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21756         $CHECKSTAT -t file $remote_file || error "check file failed"
21757 }
21758 run_test 310b "unlink remote file with multiple links while open"
21759
21760 test_310c() {
21761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21762         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21763
21764         local remote_file=$DIR/$tdir/tgt_dir/b
21765
21766         mkdir -p $DIR/$tdir
21767
21768         prepare_remote_file || error "prepare remote file failed"
21769
21770         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21771         multiop_bg_pause $remote_file O_uc ||
21772                         error "mulitop failed for remote file"
21773         MULTIPID=$!
21774         $MULTIOP $DIR/$tfile Ouc
21775         kill -USR1 $MULTIPID
21776         wait $MULTIPID
21777 }
21778 run_test 310c "open-unlink remote file with multiple links"
21779
21780 #LU-4825
21781 test_311() {
21782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21783         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21784         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21785                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21786         remote_mds_nodsh && skip "remote MDS with nodsh"
21787
21788         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21789         local mdts=$(comma_list $(mdts_nodes))
21790
21791         mkdir -p $DIR/$tdir
21792         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21793         createmany -o $DIR/$tdir/$tfile. 1000
21794
21795         # statfs data is not real time, let's just calculate it
21796         old_iused=$((old_iused + 1000))
21797
21798         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21799                         osp.*OST0000*MDT0000.create_count")
21800         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21801                                 osp.*OST0000*MDT0000.max_create_count")
21802         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21803
21804         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21805         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21806         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21807
21808         unlinkmany $DIR/$tdir/$tfile. 1000
21809
21810         do_nodes $mdts "$LCTL set_param -n \
21811                         osp.*OST0000*.max_create_count=$max_count"
21812         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21813                 do_nodes $mdts "$LCTL set_param -n \
21814                                 osp.*OST0000*.create_count=$count"
21815         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21816                         grep "=0" && error "create_count is zero"
21817
21818         local new_iused
21819         for i in $(seq 120); do
21820                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21821                 # system may be too busy to destroy all objs in time, use
21822                 # a somewhat small value to not fail autotest
21823                 [ $((old_iused - new_iused)) -gt 400 ] && break
21824                 sleep 1
21825         done
21826
21827         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21828         [ $((old_iused - new_iused)) -gt 400 ] ||
21829                 error "objs not destroyed after unlink"
21830 }
21831 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21832
21833 zfs_oid_to_objid()
21834 {
21835         local ost=$1
21836         local objid=$2
21837
21838         local vdevdir=$(dirname $(facet_vdevice $ost))
21839         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21840         local zfs_zapid=$(do_facet $ost $cmd |
21841                           grep -w "/O/0/d$((objid%32))" -C 5 |
21842                           awk '/Object/{getline; print $1}')
21843         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21844                           awk "/$objid = /"'{printf $3}')
21845
21846         echo $zfs_objid
21847 }
21848
21849 zfs_object_blksz() {
21850         local ost=$1
21851         local objid=$2
21852
21853         local vdevdir=$(dirname $(facet_vdevice $ost))
21854         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21855         local blksz=$(do_facet $ost $cmd $objid |
21856                       awk '/dblk/{getline; printf $4}')
21857
21858         case "${blksz: -1}" in
21859                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21860                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21861                 *) ;;
21862         esac
21863
21864         echo $blksz
21865 }
21866
21867 test_312() { # LU-4856
21868         remote_ost_nodsh && skip "remote OST with nodsh"
21869         [ "$ost1_FSTYPE" = "zfs" ] ||
21870                 skip_env "the test only applies to zfs"
21871
21872         local max_blksz=$(do_facet ost1 \
21873                           $ZFS get -p recordsize $(facet_device ost1) |
21874                           awk '!/VALUE/{print $3}')
21875
21876         # to make life a little bit easier
21877         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21878         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21879
21880         local tf=$DIR/$tdir/$tfile
21881         touch $tf
21882         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21883
21884         # Get ZFS object id
21885         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21886         # block size change by sequential overwrite
21887         local bs
21888
21889         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21890                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21891
21892                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21893                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21894         done
21895         rm -f $tf
21896
21897         # block size change by sequential append write
21898         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21899         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21900         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21901         local count
21902
21903         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21904                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21905                         oflag=sync conv=notrunc
21906
21907                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21908                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21909                         error "blksz error, actual $blksz, " \
21910                                 "expected: 2 * $count * $PAGE_SIZE"
21911         done
21912         rm -f $tf
21913
21914         # random write
21915         touch $tf
21916         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21917         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21918
21919         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21920         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21921         [ $blksz -eq $PAGE_SIZE ] ||
21922                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21923
21924         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21925         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21926         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21927
21928         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21929         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21930         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21931 }
21932 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21933
21934 test_313() {
21935         remote_ost_nodsh && skip "remote OST with nodsh"
21936
21937         local file=$DIR/$tfile
21938
21939         rm -f $file
21940         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21941
21942         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21943         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21944         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21945                 error "write should failed"
21946         do_facet ost1 "$LCTL set_param fail_loc=0"
21947         rm -f $file
21948 }
21949 run_test 313 "io should fail after last_rcvd update fail"
21950
21951 test_314() {
21952         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21953
21954         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21955         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21956         rm -f $DIR/$tfile
21957         wait_delete_completed
21958         do_facet ost1 "$LCTL set_param fail_loc=0"
21959 }
21960 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21961
21962 test_315() { # LU-618
21963         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21964
21965         local file=$DIR/$tfile
21966         rm -f $file
21967
21968         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21969                 error "multiop file write failed"
21970         $MULTIOP $file oO_RDONLY:r4063232_c &
21971         PID=$!
21972
21973         sleep 2
21974
21975         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21976         kill -USR1 $PID
21977
21978         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21979         rm -f $file
21980 }
21981 run_test 315 "read should be accounted"
21982
21983 test_316() {
21984         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21985         large_xattr_enabled || skip_env "ea_inode feature disabled"
21986
21987         rm -rf $DIR/$tdir/d
21988         mkdir -p $DIR/$tdir/d
21989         chown nobody $DIR/$tdir/d
21990         touch $DIR/$tdir/d/file
21991
21992         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21993 }
21994 run_test 316 "lfs mv"
21995
21996 test_317() {
21997         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21998                 skip "Need MDS version at least 2.11.53"
21999         if [ "$ost1_FSTYPE" == "zfs" ]; then
22000                 skip "LU-10370: no implementation for ZFS"
22001         fi
22002
22003         local trunc_sz
22004         local grant_blk_size
22005
22006         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22007                         awk '/grant_block_size:/ { print $2; exit; }')
22008         #
22009         # Create File of size 5M. Truncate it to below size's and verify
22010         # blocks count.
22011         #
22012         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22013                 error "Create file $DIR/$tfile failed"
22014         stack_trap "rm -f $DIR/$tfile" EXIT
22015
22016         for trunc_sz in 2097152 4097 4000 509 0; do
22017                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22018                         error "truncate $tfile to $trunc_sz failed"
22019                 local sz=$(stat --format=%s $DIR/$tfile)
22020                 local blk=$(stat --format=%b $DIR/$tfile)
22021                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22022                                      grant_blk_size) * 8))
22023
22024                 if [[ $blk -ne $trunc_blk ]]; then
22025                         $(which stat) $DIR/$tfile
22026                         error "Expected Block $trunc_blk got $blk for $tfile"
22027                 fi
22028
22029                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22030                         error "Expected Size $trunc_sz got $sz for $tfile"
22031         done
22032
22033         #
22034         # sparse file test
22035         # Create file with a hole and write actual two blocks. Block count
22036         # must be 16.
22037         #
22038         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22039                 conv=fsync || error "Create file : $DIR/$tfile"
22040
22041         # Calculate the final truncate size.
22042         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22043
22044         #
22045         # truncate to size $trunc_sz bytes. Strip the last block
22046         # The block count must drop to 8
22047         #
22048         $TRUNCATE $DIR/$tfile $trunc_sz ||
22049                 error "truncate $tfile to $trunc_sz failed"
22050
22051         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22052         sz=$(stat --format=%s $DIR/$tfile)
22053         blk=$(stat --format=%b $DIR/$tfile)
22054
22055         if [[ $blk -ne $trunc_bsz ]]; then
22056                 $(which stat) $DIR/$tfile
22057                 error "Expected Block $trunc_bsz got $blk for $tfile"
22058         fi
22059
22060         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22061                 error "Expected Size $trunc_sz got $sz for $tfile"
22062 }
22063 run_test 317 "Verify blocks get correctly update after truncate"
22064
22065 test_318() {
22066         local old_max_active=$($LCTL get_param -n \
22067                             llite.*.max_read_ahead_async_active 2>/dev/null)
22068
22069         $LCTL set_param llite.*.max_read_ahead_async_active=256
22070         local max_active=$($LCTL get_param -n \
22071                            llite.*.max_read_ahead_async_active 2>/dev/null)
22072         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22073
22074         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22075                 error "set max_read_ahead_async_active should succeed"
22076
22077         $LCTL set_param llite.*.max_read_ahead_async_active=512
22078         max_active=$($LCTL get_param -n \
22079                      llite.*.max_read_ahead_async_active 2>/dev/null)
22080         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22081
22082         # restore @max_active
22083         [ $old_max_active -ne 0 ] && $LCTL set_param \
22084                 llite.*.max_read_ahead_async_active=$old_max_active
22085
22086         local old_threshold=$($LCTL get_param -n \
22087                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22088         local max_per_file_mb=$($LCTL get_param -n \
22089                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22090
22091         local invalid=$(($max_per_file_mb + 1))
22092         $LCTL set_param \
22093                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22094                         && error "set $invalid should fail"
22095
22096         local valid=$(($invalid - 1))
22097         $LCTL set_param \
22098                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22099                         error "set $valid should succeed"
22100         local threshold=$($LCTL get_param -n \
22101                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22102         [ $threshold -eq $valid ] || error \
22103                 "expect threshold $valid got $threshold"
22104         $LCTL set_param \
22105                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22106 }
22107 run_test 318 "Verify async readahead tunables"
22108
22109 test_319() {
22110         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22111
22112         local before=$(date +%s)
22113         local evict
22114         local mdir=$DIR/$tdir
22115         local file=$mdir/xxx
22116
22117         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22118         touch $file
22119
22120 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22121         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22122         $LFS mv -m1 $file &
22123
22124         sleep 1
22125         dd if=$file of=/dev/null
22126         wait
22127         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22128           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22129
22130         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22131 }
22132 run_test 319 "lost lease lock on migrate error"
22133
22134 test_398a() { # LU-4198
22135         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22136         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22137
22138         # request a new lock on client
22139         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22140
22141         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22142         local lock_count=$($LCTL get_param -n \
22143                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22144         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22145
22146         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22147
22148         # no lock cached, should use lockless IO and not enqueue new lock
22149         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22150         lock_count=$($LCTL get_param -n \
22151                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22152         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22153 }
22154 run_test 398a "direct IO should cancel lock otherwise lockless"
22155
22156 test_398b() { # LU-4198
22157         which fio || skip_env "no fio installed"
22158         $LFS setstripe -c -1 $DIR/$tfile
22159
22160         local size=12
22161         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22162
22163         local njobs=4
22164         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22165         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22166                 --numjobs=$njobs --fallocate=none \
22167                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22168                 --filename=$DIR/$tfile &
22169         bg_pid=$!
22170
22171         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22172         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22173                 --numjobs=$njobs --fallocate=none \
22174                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22175                 --filename=$DIR/$tfile || true
22176         wait $bg_pid
22177
22178         rm -rf $DIR/$tfile
22179 }
22180 run_test 398b "DIO and buffer IO race"
22181
22182 test_398c() { # LU-4198
22183         which fio || skip_env "no fio installed"
22184
22185         saved_debug=$($LCTL get_param -n debug)
22186         $LCTL set_param debug=0
22187
22188         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22189         ((size /= 1024)) # by megabytes
22190         ((size /= 2)) # write half of the OST at most
22191         [ $size -gt 40 ] && size=40 #reduce test time anyway
22192
22193         $LFS setstripe -c 1 $DIR/$tfile
22194
22195         # it seems like ldiskfs reserves more space than necessary if the
22196         # writing blocks are not mapped, so it extends the file firstly
22197         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22198         cancel_lru_locks osc
22199
22200         # clear and verify rpc_stats later
22201         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22202
22203         local njobs=4
22204         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22205         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22206                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22207                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22208                 --filename=$DIR/$tfile
22209         [ $? -eq 0 ] || error "fio write error"
22210
22211         [ $($LCTL get_param -n \
22212          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22213                 error "Locks were requested while doing AIO"
22214
22215         # get the percentage of 1-page I/O
22216         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22217                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22218                 awk '{print $7}')
22219         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22220
22221         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22222         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22223                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22224                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22225                 --filename=$DIR/$tfile
22226         [ $? -eq 0 ] || error "fio mixed read write error"
22227
22228         echo "AIO with large block size ${size}M"
22229         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22230                 --numjobs=1 --fallocate=none --ioengine=libaio \
22231                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22232                 --filename=$DIR/$tfile
22233         [ $? -eq 0 ] || error "fio large block size failed"
22234
22235         rm -rf $DIR/$tfile
22236         $LCTL set_param debug="$saved_debug"
22237 }
22238 run_test 398c "run fio to test AIO"
22239
22240 test_398d() { #  LU-13846
22241         test -f aiocp || skip_env "no aiocp installed"
22242         local aio_file=$DIR/aio_file
22243
22244         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22245
22246         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22247         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22248
22249         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22250
22251         # make sure we don't crash and fail properly
22252         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22253                 error "aio not aligned with PAGE SIZE should fail"
22254
22255         rm -rf $DIR/$tfile $aio_file
22256 }
22257 run_test 398d "run aiocp to verify block size > stripe size"
22258
22259 test_fake_rw() {
22260         local read_write=$1
22261         if [ "$read_write" = "write" ]; then
22262                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22263         elif [ "$read_write" = "read" ]; then
22264                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22265         else
22266                 error "argument error"
22267         fi
22268
22269         # turn off debug for performance testing
22270         local saved_debug=$($LCTL get_param -n debug)
22271         $LCTL set_param debug=0
22272
22273         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22274
22275         # get ost1 size - $FSNAME-OST0000
22276         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22277         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22278         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22279
22280         if [ "$read_write" = "read" ]; then
22281                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22282         fi
22283
22284         local start_time=$(date +%s.%N)
22285         $dd_cmd bs=1M count=$blocks oflag=sync ||
22286                 error "real dd $read_write error"
22287         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22288
22289         if [ "$read_write" = "write" ]; then
22290                 rm -f $DIR/$tfile
22291         fi
22292
22293         # define OBD_FAIL_OST_FAKE_RW           0x238
22294         do_facet ost1 $LCTL set_param fail_loc=0x238
22295
22296         local start_time=$(date +%s.%N)
22297         $dd_cmd bs=1M count=$blocks oflag=sync ||
22298                 error "fake dd $read_write error"
22299         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22300
22301         if [ "$read_write" = "write" ]; then
22302                 # verify file size
22303                 cancel_lru_locks osc
22304                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22305                         error "$tfile size not $blocks MB"
22306         fi
22307         do_facet ost1 $LCTL set_param fail_loc=0
22308
22309         echo "fake $read_write $duration_fake vs. normal $read_write" \
22310                 "$duration in seconds"
22311         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22312                 error_not_in_vm "fake write is slower"
22313
22314         $LCTL set_param -n debug="$saved_debug"
22315         rm -f $DIR/$tfile
22316 }
22317 test_399a() { # LU-7655 for OST fake write
22318         remote_ost_nodsh && skip "remote OST with nodsh"
22319
22320         test_fake_rw write
22321 }
22322 run_test 399a "fake write should not be slower than normal write"
22323
22324 test_399b() { # LU-8726 for OST fake read
22325         remote_ost_nodsh && skip "remote OST with nodsh"
22326         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22327                 skip_env "ldiskfs only test"
22328         fi
22329
22330         test_fake_rw read
22331 }
22332 run_test 399b "fake read should not be slower than normal read"
22333
22334 test_400a() { # LU-1606, was conf-sanity test_74
22335         if ! which $CC > /dev/null 2>&1; then
22336                 skip_env "$CC is not installed"
22337         fi
22338
22339         local extra_flags=''
22340         local out=$TMP/$tfile
22341         local prefix=/usr/include/lustre
22342         local prog
22343
22344         # Oleg removes c files in his test rig so test if any c files exist
22345         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22346                 skip_env "Needed c test files are missing"
22347
22348         if ! [[ -d $prefix ]]; then
22349                 # Assume we're running in tree and fixup the include path.
22350                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22351                 extra_flags+=" -L$LUSTRE/utils/.lib"
22352         fi
22353
22354         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22355                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22356                         error "client api broken"
22357         done
22358         rm -f $out
22359 }
22360 run_test 400a "Lustre client api program can compile and link"
22361
22362 test_400b() { # LU-1606, LU-5011
22363         local header
22364         local out=$TMP/$tfile
22365         local prefix=/usr/include/linux/lustre
22366
22367         # We use a hard coded prefix so that this test will not fail
22368         # when run in tree. There are headers in lustre/include/lustre/
22369         # that are not packaged (like lustre_idl.h) and have more
22370         # complicated include dependencies (like config.h and lnet/types.h).
22371         # Since this test about correct packaging we just skip them when
22372         # they don't exist (see below) rather than try to fixup cppflags.
22373
22374         if ! which $CC > /dev/null 2>&1; then
22375                 skip_env "$CC is not installed"
22376         fi
22377
22378         for header in $prefix/*.h; do
22379                 if ! [[ -f "$header" ]]; then
22380                         continue
22381                 fi
22382
22383                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22384                         continue # lustre_ioctl.h is internal header
22385                 fi
22386
22387                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22388                         error "cannot compile '$header'"
22389         done
22390         rm -f $out
22391 }
22392 run_test 400b "packaged headers can be compiled"
22393
22394 test_401a() { #LU-7437
22395         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22396         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22397
22398         #count the number of parameters by "list_param -R"
22399         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22400         #count the number of parameters by listing proc files
22401         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22402         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22403         echo "proc_dirs='$proc_dirs'"
22404         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22405         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22406                       sort -u | wc -l)
22407
22408         [ $params -eq $procs ] ||
22409                 error "found $params parameters vs. $procs proc files"
22410
22411         # test the list_param -D option only returns directories
22412         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22413         #count the number of parameters by listing proc directories
22414         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22415                 sort -u | wc -l)
22416
22417         [ $params -eq $procs ] ||
22418                 error "found $params parameters vs. $procs proc files"
22419 }
22420 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22421
22422 test_401b() {
22423         # jobid_var may not allow arbitrary values, so use jobid_name
22424         # if available
22425         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22426                 local testname=jobid_name tmp='testing%p'
22427         else
22428                 local testname=jobid_var tmp=testing
22429         fi
22430
22431         local save=$($LCTL get_param -n $testname)
22432
22433         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22434                 error "no error returned when setting bad parameters"
22435
22436         local jobid_new=$($LCTL get_param -n foe $testname baz)
22437         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22438
22439         $LCTL set_param -n fog=bam $testname=$save bat=fog
22440         local jobid_old=$($LCTL get_param -n foe $testname bag)
22441         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22442 }
22443 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22444
22445 test_401c() {
22446         # jobid_var may not allow arbitrary values, so use jobid_name
22447         # if available
22448         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22449                 local testname=jobid_name
22450         else
22451                 local testname=jobid_var
22452         fi
22453
22454         local jobid_var_old=$($LCTL get_param -n $testname)
22455         local jobid_var_new
22456
22457         $LCTL set_param $testname= &&
22458                 error "no error returned for 'set_param a='"
22459
22460         jobid_var_new=$($LCTL get_param -n $testname)
22461         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22462                 error "$testname was changed by setting without value"
22463
22464         $LCTL set_param $testname &&
22465                 error "no error returned for 'set_param a'"
22466
22467         jobid_var_new=$($LCTL get_param -n $testname)
22468         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22469                 error "$testname was changed by setting without value"
22470 }
22471 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22472
22473 test_401d() {
22474         # jobid_var may not allow arbitrary values, so use jobid_name
22475         # if available
22476         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22477                 local testname=jobid_name new_value='foo=bar%p'
22478         else
22479                 local testname=jobid_var new_valuie=foo=bar
22480         fi
22481
22482         local jobid_var_old=$($LCTL get_param -n $testname)
22483         local jobid_var_new
22484
22485         $LCTL set_param $testname=$new_value ||
22486                 error "'set_param a=b' did not accept a value containing '='"
22487
22488         jobid_var_new=$($LCTL get_param -n $testname)
22489         [[ "$jobid_var_new" == "$new_value" ]] ||
22490                 error "'set_param a=b' failed on a value containing '='"
22491
22492         # Reset the $testname to test the other format
22493         $LCTL set_param $testname=$jobid_var_old
22494         jobid_var_new=$($LCTL get_param -n $testname)
22495         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22496                 error "failed to reset $testname"
22497
22498         $LCTL set_param $testname $new_value ||
22499                 error "'set_param a b' did not accept a value containing '='"
22500
22501         jobid_var_new=$($LCTL get_param -n $testname)
22502         [[ "$jobid_var_new" == "$new_value" ]] ||
22503                 error "'set_param a b' failed on a value containing '='"
22504
22505         $LCTL set_param $testname $jobid_var_old
22506         jobid_var_new=$($LCTL get_param -n $testname)
22507         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22508                 error "failed to reset $testname"
22509 }
22510 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22511
22512 test_402() {
22513         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22514         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22515                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22516         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22517                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22518                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22519         remote_mds_nodsh && skip "remote MDS with nodsh"
22520
22521         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22522 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22523         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22524         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22525                 echo "Touch failed - OK"
22526 }
22527 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22528
22529 test_403() {
22530         local file1=$DIR/$tfile.1
22531         local file2=$DIR/$tfile.2
22532         local tfile=$TMP/$tfile
22533
22534         rm -f $file1 $file2 $tfile
22535
22536         touch $file1
22537         ln $file1 $file2
22538
22539         # 30 sec OBD_TIMEOUT in ll_getattr()
22540         # right before populating st_nlink
22541         $LCTL set_param fail_loc=0x80001409
22542         stat -c %h $file1 > $tfile &
22543
22544         # create an alias, drop all locks and reclaim the dentry
22545         < $file2
22546         cancel_lru_locks mdc
22547         cancel_lru_locks osc
22548         sysctl -w vm.drop_caches=2
22549
22550         wait
22551
22552         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22553
22554         rm -f $tfile $file1 $file2
22555 }
22556 run_test 403 "i_nlink should not drop to zero due to aliasing"
22557
22558 test_404() { # LU-6601
22559         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22560                 skip "Need server version newer than 2.8.52"
22561         remote_mds_nodsh && skip "remote MDS with nodsh"
22562
22563         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22564                 awk '/osp .*-osc-MDT/ { print $4}')
22565
22566         local osp
22567         for osp in $mosps; do
22568                 echo "Deactivate: " $osp
22569                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22570                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22571                         awk -vp=$osp '$4 == p { print $2 }')
22572                 [ $stat = IN ] || {
22573                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22574                         error "deactivate error"
22575                 }
22576                 echo "Activate: " $osp
22577                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22578                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22579                         awk -vp=$osp '$4 == p { print $2 }')
22580                 [ $stat = UP ] || {
22581                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22582                         error "activate error"
22583                 }
22584         done
22585 }
22586 run_test 404 "validate manual {de}activated works properly for OSPs"
22587
22588 test_405() {
22589         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22590         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22591                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22592                         skip "Layout swap lock is not supported"
22593
22594         check_swap_layouts_support
22595         check_swap_layout_no_dom $DIR
22596
22597         test_mkdir $DIR/$tdir
22598         swap_lock_test -d $DIR/$tdir ||
22599                 error "One layout swap locked test failed"
22600 }
22601 run_test 405 "Various layout swap lock tests"
22602
22603 test_406() {
22604         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22605         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22606         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22608         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22609                 skip "Need MDS version at least 2.8.50"
22610
22611         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22612         local test_pool=$TESTNAME
22613
22614         pool_add $test_pool || error "pool_add failed"
22615         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22616                 error "pool_add_targets failed"
22617
22618         save_layout_restore_at_exit $MOUNT
22619
22620         # parent set default stripe count only, child will stripe from both
22621         # parent and fs default
22622         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22623                 error "setstripe $MOUNT failed"
22624         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22625         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22626         for i in $(seq 10); do
22627                 local f=$DIR/$tdir/$tfile.$i
22628                 touch $f || error "touch failed"
22629                 local count=$($LFS getstripe -c $f)
22630                 [ $count -eq $OSTCOUNT ] ||
22631                         error "$f stripe count $count != $OSTCOUNT"
22632                 local offset=$($LFS getstripe -i $f)
22633                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22634                 local size=$($LFS getstripe -S $f)
22635                 [ $size -eq $((def_stripe_size * 2)) ] ||
22636                         error "$f stripe size $size != $((def_stripe_size * 2))"
22637                 local pool=$($LFS getstripe -p $f)
22638                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22639         done
22640
22641         # change fs default striping, delete parent default striping, now child
22642         # will stripe from new fs default striping only
22643         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22644                 error "change $MOUNT default stripe failed"
22645         $LFS setstripe -c 0 $DIR/$tdir ||
22646                 error "delete $tdir default stripe failed"
22647         for i in $(seq 11 20); do
22648                 local f=$DIR/$tdir/$tfile.$i
22649                 touch $f || error "touch $f failed"
22650                 local count=$($LFS getstripe -c $f)
22651                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22652                 local offset=$($LFS getstripe -i $f)
22653                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22654                 local size=$($LFS getstripe -S $f)
22655                 [ $size -eq $def_stripe_size ] ||
22656                         error "$f stripe size $size != $def_stripe_size"
22657                 local pool=$($LFS getstripe -p $f)
22658                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22659         done
22660
22661         unlinkmany $DIR/$tdir/$tfile. 1 20
22662
22663         local f=$DIR/$tdir/$tfile
22664         pool_remove_all_targets $test_pool $f
22665         pool_remove $test_pool $f
22666 }
22667 run_test 406 "DNE support fs default striping"
22668
22669 test_407() {
22670         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22671         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22672                 skip "Need MDS version at least 2.8.55"
22673         remote_mds_nodsh && skip "remote MDS with nodsh"
22674
22675         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22676                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22677         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22678                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22679         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22680
22681         #define OBD_FAIL_DT_TXN_STOP    0x2019
22682         for idx in $(seq $MDSCOUNT); do
22683                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22684         done
22685         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22686         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22687                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22688         true
22689 }
22690 run_test 407 "transaction fail should cause operation fail"
22691
22692 test_408() {
22693         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22694
22695         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22696         lctl set_param fail_loc=0x8000040a
22697         # let ll_prepare_partial_page() fail
22698         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22699
22700         rm -f $DIR/$tfile
22701
22702         # create at least 100 unused inodes so that
22703         # shrink_icache_memory(0) should not return 0
22704         touch $DIR/$tfile-{0..100}
22705         rm -f $DIR/$tfile-{0..100}
22706         sync
22707
22708         echo 2 > /proc/sys/vm/drop_caches
22709 }
22710 run_test 408 "drop_caches should not hang due to page leaks"
22711
22712 test_409()
22713 {
22714         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22715
22716         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22717         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22718         touch $DIR/$tdir/guard || error "(2) Fail to create"
22719
22720         local PREFIX=$(str_repeat 'A' 128)
22721         echo "Create 1K hard links start at $(date)"
22722         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22723                 error "(3) Fail to hard link"
22724
22725         echo "Links count should be right although linkEA overflow"
22726         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22727         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22728         [ $linkcount -eq 1001 ] ||
22729                 error "(5) Unexpected hard links count: $linkcount"
22730
22731         echo "List all links start at $(date)"
22732         ls -l $DIR/$tdir/foo > /dev/null ||
22733                 error "(6) Fail to list $DIR/$tdir/foo"
22734
22735         echo "Unlink hard links start at $(date)"
22736         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22737                 error "(7) Fail to unlink"
22738         echo "Unlink hard links finished at $(date)"
22739 }
22740 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22741
22742 test_410()
22743 {
22744         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22745                 skip "Need client version at least 2.9.59"
22746         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22747                 skip "Need MODULES build"
22748
22749         # Create a file, and stat it from the kernel
22750         local testfile=$DIR/$tfile
22751         touch $testfile
22752
22753         local run_id=$RANDOM
22754         local my_ino=$(stat --format "%i" $testfile)
22755
22756         # Try to insert the module. This will always fail as the
22757         # module is designed to not be inserted.
22758         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22759             &> /dev/null
22760
22761         # Anything but success is a test failure
22762         dmesg | grep -q \
22763             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22764             error "no inode match"
22765 }
22766 run_test 410 "Test inode number returned from kernel thread"
22767
22768 cleanup_test411_cgroup() {
22769         trap 0
22770         rmdir "$1"
22771 }
22772
22773 test_411() {
22774         local cg_basedir=/sys/fs/cgroup/memory
22775         # LU-9966
22776         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22777                 skip "no setup for cgroup"
22778
22779         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22780                 error "test file creation failed"
22781         cancel_lru_locks osc
22782
22783         # Create a very small memory cgroup to force a slab allocation error
22784         local cgdir=$cg_basedir/osc_slab_alloc
22785         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22786         trap "cleanup_test411_cgroup $cgdir" EXIT
22787         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22788         echo 1M > $cgdir/memory.limit_in_bytes
22789
22790         # Should not LBUG, just be killed by oom-killer
22791         # dd will return 0 even allocation failure in some environment.
22792         # So don't check return value
22793         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22794         cleanup_test411_cgroup $cgdir
22795
22796         return 0
22797 }
22798 run_test 411 "Slab allocation error with cgroup does not LBUG"
22799
22800 test_412() {
22801         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22802         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22803                 skip "Need server version at least 2.10.55"
22804         fi
22805
22806         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22807                 error "mkdir failed"
22808         $LFS getdirstripe $DIR/$tdir
22809         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22810         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22811                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22812         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22813         [ $stripe_count -eq 2 ] ||
22814                 error "expect 2 get $stripe_count"
22815 }
22816 run_test 412 "mkdir on specific MDTs"
22817
22818 test_qos_mkdir() {
22819         local mkdir_cmd=$1
22820         local stripe_count=$2
22821         local mdts=$(comma_list $(mdts_nodes))
22822
22823         local testdir
22824         local lmv_qos_prio_free
22825         local lmv_qos_threshold_rr
22826         local lmv_qos_maxage
22827         local lod_qos_prio_free
22828         local lod_qos_threshold_rr
22829         local lod_qos_maxage
22830         local count
22831         local i
22832
22833         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22834         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22835         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22836                 head -n1)
22837         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22838         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22839         stack_trap "$LCTL set_param \
22840                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22841         stack_trap "$LCTL set_param \
22842                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22843         stack_trap "$LCTL set_param \
22844                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22845
22846         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22847                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22848         lod_qos_prio_free=${lod_qos_prio_free%%%}
22849         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22850                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22851         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22852         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22853                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22854         stack_trap "do_nodes $mdts $LCTL set_param \
22855                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22856         stack_trap "do_nodes $mdts $LCTL set_param \
22857                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22858                 EXIT
22859         stack_trap "do_nodes $mdts $LCTL set_param \
22860                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22861
22862         echo
22863         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22864
22865         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22866         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22867
22868         testdir=$DIR/$tdir-s$stripe_count/rr
22869
22870         for i in $(seq $((100 * MDSCOUNT))); do
22871                 eval $mkdir_cmd $testdir/subdir$i ||
22872                         error "$mkdir_cmd subdir$i failed"
22873         done
22874
22875         for i in $(seq $MDSCOUNT); do
22876                 count=$($LFS getdirstripe -i $testdir/* |
22877                                 grep ^$((i - 1))$ | wc -l)
22878                 echo "$count directories created on MDT$((i - 1))"
22879                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22880
22881                 if [ $stripe_count -gt 1 ]; then
22882                         count=$($LFS getdirstripe $testdir/* |
22883                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22884                         echo "$count stripes created on MDT$((i - 1))"
22885                         # deviation should < 5% of average
22886                         [ $count -lt $((95 * stripe_count)) ] ||
22887                         [ $count -gt $((105 * stripe_count)) ] &&
22888                                 error "stripes are not evenly distributed"
22889                 fi
22890         done
22891
22892         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22893         do_nodes $mdts $LCTL set_param \
22894                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22895
22896         echo
22897         echo "Check for uneven MDTs: "
22898
22899         local ffree
22900         local bavail
22901         local max
22902         local min
22903         local max_index
22904         local min_index
22905         local tmp
22906
22907         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22908         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22909         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22910
22911         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22912         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22913         max_index=0
22914         min_index=0
22915         for ((i = 1; i < ${#ffree[@]}; i++)); do
22916                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22917                 if [ $tmp -gt $max ]; then
22918                         max=$tmp
22919                         max_index=$i
22920                 fi
22921                 if [ $tmp -lt $min ]; then
22922                         min=$tmp
22923                         min_index=$i
22924                 fi
22925         done
22926
22927         [ ${ffree[min_index]} -eq 0 ] &&
22928                 skip "no free files in MDT$min_index"
22929         [ ${ffree[min_index]} -gt 100000000 ] &&
22930                 skip "too much free files in MDT$min_index"
22931
22932         # Check if we need to generate uneven MDTs
22933         local threshold=50
22934         local diff=$(((max - min) * 100 / min))
22935         local value="$(generate_string 1024)"
22936
22937         while [ $diff -lt $threshold ]; do
22938                 # generate uneven MDTs, create till $threshold% diff
22939                 echo -n "weight diff=$diff% must be > $threshold% ..."
22940                 count=$((${ffree[min_index]} / 10))
22941                 # 50 sec per 10000 files in vm
22942                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22943                         skip "$count files to create"
22944                 echo "Fill MDT$min_index with $count files"
22945                 [ -d $DIR/$tdir-MDT$min_index ] ||
22946                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22947                         error "mkdir $tdir-MDT$min_index failed"
22948                 for i in $(seq $count); do
22949                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22950                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22951                                 error "create f$j_$i failed"
22952                         setfattr -n user.413b -v $value \
22953                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22954                                 error "setfattr f$j_$i failed"
22955                 done
22956
22957                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22958                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22959                 max=$(((${ffree[max_index]} >> 8) * \
22960                         (${bavail[max_index]} * bsize >> 16)))
22961                 min=$(((${ffree[min_index]} >> 8) * \
22962                         (${bavail[min_index]} * bsize >> 16)))
22963                 diff=$(((max - min) * 100 / min))
22964         done
22965
22966         echo "MDT filesfree available: ${ffree[@]}"
22967         echo "MDT blocks available: ${bavail[@]}"
22968         echo "weight diff=$diff%"
22969
22970         echo
22971         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22972
22973         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22974         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22975         # decrease statfs age, so that it can be updated in time
22976         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22977         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22978
22979         sleep 1
22980
22981         testdir=$DIR/$tdir-s$stripe_count/qos
22982
22983         for i in $(seq $((100 * MDSCOUNT))); do
22984                 eval $mkdir_cmd $testdir/subdir$i ||
22985                         error "$mkdir_cmd subdir$i failed"
22986         done
22987
22988         for i in $(seq $MDSCOUNT); do
22989                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22990                         wc -l)
22991                 echo "$count directories created on MDT$((i - 1))"
22992
22993                 if [ $stripe_count -gt 1 ]; then
22994                         count=$($LFS getdirstripe $testdir/* |
22995                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22996                         echo "$count stripes created on MDT$((i - 1))"
22997                 fi
22998         done
22999
23000         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23001         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23002
23003         # D-value should > 10% of averge
23004         [ $((max - min)) -lt 10 ] &&
23005                 error "subdirs shouldn't be evenly distributed"
23006
23007         # ditto
23008         if [ $stripe_count -gt 1 ]; then
23009                 max=$($LFS getdirstripe $testdir/* |
23010                         grep -P "^\s+$max_index\t" | wc -l)
23011                 min=$($LFS getdirstripe $testdir/* |
23012                         grep -P "^\s+$min_index\t" | wc -l)
23013                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23014                         error "stripes shouldn't be evenly distributed"|| true
23015         fi
23016 }
23017
23018 test_413a() {
23019         [ $MDSCOUNT -lt 2 ] &&
23020                 skip "We need at least 2 MDTs for this test"
23021
23022         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23023                 skip "Need server version at least 2.12.52"
23024
23025         local stripe_count
23026
23027         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23028                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23029                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23030                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23031                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23032         done
23033 }
23034 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23035
23036 test_413b() {
23037         [ $MDSCOUNT -lt 2 ] &&
23038                 skip "We need at least 2 MDTs for this test"
23039
23040         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23041                 skip "Need server version at least 2.12.52"
23042
23043         local stripe_count
23044
23045         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23046                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23047                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23048                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23049                 $LFS setdirstripe -D -c $stripe_count \
23050                         $DIR/$tdir-s$stripe_count/rr ||
23051                         error "setdirstripe failed"
23052                 $LFS setdirstripe -D -c $stripe_count \
23053                         $DIR/$tdir-s$stripe_count/qos ||
23054                         error "setdirstripe failed"
23055                 test_qos_mkdir "mkdir" $stripe_count
23056         done
23057 }
23058 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23059
23060 test_414() {
23061 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23062         $LCTL set_param fail_loc=0x80000521
23063         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23064         rm -f $DIR/$tfile
23065 }
23066 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23067
23068 test_415() {
23069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23070         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23071                 skip "Need server version at least 2.11.52"
23072
23073         # LU-11102
23074         local total
23075         local setattr_pid
23076         local start_time
23077         local end_time
23078         local duration
23079
23080         total=500
23081         # this test may be slow on ZFS
23082         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23083
23084         # though this test is designed for striped directory, let's test normal
23085         # directory too since lock is always saved as CoS lock.
23086         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23087         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23088
23089         (
23090                 while true; do
23091                         touch $DIR/$tdir
23092                 done
23093         ) &
23094         setattr_pid=$!
23095
23096         start_time=$(date +%s)
23097         for i in $(seq $total); do
23098                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23099                         > /dev/null
23100         done
23101         end_time=$(date +%s)
23102         duration=$((end_time - start_time))
23103
23104         kill -9 $setattr_pid
23105
23106         echo "rename $total files took $duration sec"
23107         [ $duration -lt 100 ] || error "rename took $duration sec"
23108 }
23109 run_test 415 "lock revoke is not missing"
23110
23111 test_416() {
23112         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23113                 skip "Need server version at least 2.11.55"
23114
23115         # define OBD_FAIL_OSD_TXN_START    0x19a
23116         do_facet mds1 lctl set_param fail_loc=0x19a
23117
23118         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23119
23120         true
23121 }
23122 run_test 416 "transaction start failure won't cause system hung"
23123
23124 cleanup_417() {
23125         trap 0
23126         do_nodes $(comma_list $(mdts_nodes)) \
23127                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23128         do_nodes $(comma_list $(mdts_nodes)) \
23129                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23130         do_nodes $(comma_list $(mdts_nodes)) \
23131                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23132 }
23133
23134 test_417() {
23135         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23136         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23137                 skip "Need MDS version at least 2.11.56"
23138
23139         trap cleanup_417 RETURN EXIT
23140
23141         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23142         do_nodes $(comma_list $(mdts_nodes)) \
23143                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23144         $LFS migrate -m 0 $DIR/$tdir.1 &&
23145                 error "migrate dir $tdir.1 should fail"
23146
23147         do_nodes $(comma_list $(mdts_nodes)) \
23148                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23149         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23150                 error "create remote dir $tdir.2 should fail"
23151
23152         do_nodes $(comma_list $(mdts_nodes)) \
23153                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23154         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23155                 error "create striped dir $tdir.3 should fail"
23156         true
23157 }
23158 run_test 417 "disable remote dir, striped dir and dir migration"
23159
23160 # Checks that the outputs of df [-i] and lfs df [-i] match
23161 #
23162 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23163 check_lfs_df() {
23164         local dir=$2
23165         local inodes
23166         local df_out
23167         local lfs_df_out
23168         local count
23169         local passed=false
23170
23171         # blocks or inodes
23172         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23173
23174         for count in {1..100}; do
23175                 cancel_lru_locks
23176                 sync; sleep 0.2
23177
23178                 # read the lines of interest
23179                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23180                         error "df $inodes $dir | tail -n +2 failed"
23181                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23182                         error "lfs df $inodes $dir | grep summary: failed"
23183
23184                 # skip first substrings of each output as they are different
23185                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23186                 # compare the two outputs
23187                 passed=true
23188                 for i in {1..5}; do
23189                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23190                 done
23191                 $passed && break
23192         done
23193
23194         if ! $passed; then
23195                 df -P $inodes $dir
23196                 echo
23197                 lfs df $inodes $dir
23198                 error "df and lfs df $1 output mismatch: "      \
23199                       "df ${inodes}: ${df_out[*]}, "            \
23200                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23201         fi
23202 }
23203
23204 test_418() {
23205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23206
23207         local dir=$DIR/$tdir
23208         local numfiles=$((RANDOM % 4096 + 2))
23209         local numblocks=$((RANDOM % 256 + 1))
23210
23211         wait_delete_completed
23212         test_mkdir $dir
23213
23214         # check block output
23215         check_lfs_df blocks $dir
23216         # check inode output
23217         check_lfs_df inodes $dir
23218
23219         # create a single file and retest
23220         echo "Creating a single file and testing"
23221         createmany -o $dir/$tfile- 1 &>/dev/null ||
23222                 error "creating 1 file in $dir failed"
23223         check_lfs_df blocks $dir
23224         check_lfs_df inodes $dir
23225
23226         # create a random number of files
23227         echo "Creating $((numfiles - 1)) files and testing"
23228         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23229                 error "creating $((numfiles - 1)) files in $dir failed"
23230
23231         # write a random number of blocks to the first test file
23232         echo "Writing $numblocks 4K blocks and testing"
23233         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23234                 count=$numblocks &>/dev/null ||
23235                 error "dd to $dir/${tfile}-0 failed"
23236
23237         # retest
23238         check_lfs_df blocks $dir
23239         check_lfs_df inodes $dir
23240
23241         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23242                 error "unlinking $numfiles files in $dir failed"
23243 }
23244 run_test 418 "df and lfs df outputs match"
23245
23246 test_419()
23247 {
23248         local dir=$DIR/$tdir
23249
23250         mkdir -p $dir
23251         touch $dir/file
23252
23253         cancel_lru_locks mdc
23254
23255         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23256         $LCTL set_param fail_loc=0x1410
23257         cat $dir/file
23258         $LCTL set_param fail_loc=0
23259         rm -rf $dir
23260 }
23261 run_test 419 "Verify open file by name doesn't crash kernel"
23262
23263 test_420()
23264 {
23265         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23266                 skip "Need MDS version at least 2.12.53"
23267
23268         local SAVE_UMASK=$(umask)
23269         local dir=$DIR/$tdir
23270         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23271
23272         mkdir -p $dir
23273         umask 0000
23274         mkdir -m03777 $dir/testdir
23275         ls -dn $dir/testdir
23276         # Need to remove trailing '.' when SELinux is enabled
23277         local dirperms=$(ls -dn $dir/testdir |
23278                          awk '{ sub(/\.$/, "", $1); print $1}')
23279         [ $dirperms == "drwxrwsrwt" ] ||
23280                 error "incorrect perms on $dir/testdir"
23281
23282         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23283                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23284         ls -n $dir/testdir/testfile
23285         local fileperms=$(ls -n $dir/testdir/testfile |
23286                           awk '{ sub(/\.$/, "", $1); print $1}')
23287         [ $fileperms == "-rwxr-xr-x" ] ||
23288                 error "incorrect perms on $dir/testdir/testfile"
23289
23290         umask $SAVE_UMASK
23291 }
23292 run_test 420 "clear SGID bit on non-directories for non-members"
23293
23294 test_421a() {
23295         local cnt
23296         local fid1
23297         local fid2
23298
23299         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23300                 skip "Need MDS version at least 2.12.54"
23301
23302         test_mkdir $DIR/$tdir
23303         createmany -o $DIR/$tdir/f 3
23304         cnt=$(ls -1 $DIR/$tdir | wc -l)
23305         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23306
23307         fid1=$(lfs path2fid $DIR/$tdir/f1)
23308         fid2=$(lfs path2fid $DIR/$tdir/f2)
23309         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23310
23311         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23312         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23313
23314         cnt=$(ls -1 $DIR/$tdir | wc -l)
23315         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23316
23317         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23318         createmany -o $DIR/$tdir/f 3
23319         cnt=$(ls -1 $DIR/$tdir | wc -l)
23320         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23321
23322         fid1=$(lfs path2fid $DIR/$tdir/f1)
23323         fid2=$(lfs path2fid $DIR/$tdir/f2)
23324         echo "remove using fsname $FSNAME"
23325         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23326
23327         cnt=$(ls -1 $DIR/$tdir | wc -l)
23328         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23329 }
23330 run_test 421a "simple rm by fid"
23331
23332 test_421b() {
23333         local cnt
23334         local FID1
23335         local FID2
23336
23337         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23338                 skip "Need MDS version at least 2.12.54"
23339
23340         test_mkdir $DIR/$tdir
23341         createmany -o $DIR/$tdir/f 3
23342         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23343         MULTIPID=$!
23344
23345         FID1=$(lfs path2fid $DIR/$tdir/f1)
23346         FID2=$(lfs path2fid $DIR/$tdir/f2)
23347         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23348
23349         kill -USR1 $MULTIPID
23350         wait
23351
23352         cnt=$(ls $DIR/$tdir | wc -l)
23353         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23354 }
23355 run_test 421b "rm by fid on open file"
23356
23357 test_421c() {
23358         local cnt
23359         local FIDS
23360
23361         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23362                 skip "Need MDS version at least 2.12.54"
23363
23364         test_mkdir $DIR/$tdir
23365         createmany -o $DIR/$tdir/f 3
23366         touch $DIR/$tdir/$tfile
23367         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23368         cnt=$(ls -1 $DIR/$tdir | wc -l)
23369         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23370
23371         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23372         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23373
23374         cnt=$(ls $DIR/$tdir | wc -l)
23375         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23376 }
23377 run_test 421c "rm by fid against hardlinked files"
23378
23379 test_421d() {
23380         local cnt
23381         local FIDS
23382
23383         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23384                 skip "Need MDS version at least 2.12.54"
23385
23386         test_mkdir $DIR/$tdir
23387         createmany -o $DIR/$tdir/f 4097
23388         cnt=$(ls -1 $DIR/$tdir | wc -l)
23389         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23390
23391         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23392         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23393
23394         cnt=$(ls $DIR/$tdir | wc -l)
23395         rm -rf $DIR/$tdir
23396         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23397 }
23398 run_test 421d "rmfid en masse"
23399
23400 test_421e() {
23401         local cnt
23402         local FID
23403
23404         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23405         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23406                 skip "Need MDS version at least 2.12.54"
23407
23408         mkdir -p $DIR/$tdir
23409         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23410         createmany -o $DIR/$tdir/striped_dir/f 512
23411         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23412         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23413
23414         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23415                 sed "s/[/][^:]*://g")
23416         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23417
23418         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23419         rm -rf $DIR/$tdir
23420         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23421 }
23422 run_test 421e "rmfid in DNE"
23423
23424 test_421f() {
23425         local cnt
23426         local FID
23427
23428         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23429                 skip "Need MDS version at least 2.12.54"
23430
23431         test_mkdir $DIR/$tdir
23432         touch $DIR/$tdir/f
23433         cnt=$(ls -1 $DIR/$tdir | wc -l)
23434         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23435
23436         FID=$(lfs path2fid $DIR/$tdir/f)
23437         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23438         # rmfid should fail
23439         cnt=$(ls -1 $DIR/$tdir | wc -l)
23440         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23441
23442         chmod a+rw $DIR/$tdir
23443         ls -la $DIR/$tdir
23444         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23445         # rmfid should fail
23446         cnt=$(ls -1 $DIR/$tdir | wc -l)
23447         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23448
23449         rm -f $DIR/$tdir/f
23450         $RUNAS touch $DIR/$tdir/f
23451         FID=$(lfs path2fid $DIR/$tdir/f)
23452         echo "rmfid as root"
23453         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23454         cnt=$(ls -1 $DIR/$tdir | wc -l)
23455         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23456
23457         rm -f $DIR/$tdir/f
23458         $RUNAS touch $DIR/$tdir/f
23459         cnt=$(ls -1 $DIR/$tdir | wc -l)
23460         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23461         FID=$(lfs path2fid $DIR/$tdir/f)
23462         # rmfid w/o user_fid2path mount option should fail
23463         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23464         cnt=$(ls -1 $DIR/$tdir | wc -l)
23465         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23466
23467         umount_client $MOUNT || error "failed to umount client"
23468         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23469                 error "failed to mount client'"
23470
23471         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23472         # rmfid should succeed
23473         cnt=$(ls -1 $DIR/$tdir | wc -l)
23474         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23475
23476         # rmfid shouldn't allow to remove files due to dir's permission
23477         chmod a+rwx $DIR/$tdir
23478         touch $DIR/$tdir/f
23479         ls -la $DIR/$tdir
23480         FID=$(lfs path2fid $DIR/$tdir/f)
23481         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23482
23483         umount_client $MOUNT || error "failed to umount client"
23484         mount_client $MOUNT "$MOUNT_OPTS" ||
23485                 error "failed to mount client'"
23486
23487 }
23488 run_test 421f "rmfid checks permissions"
23489
23490 test_421g() {
23491         local cnt
23492         local FIDS
23493
23494         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23495         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23496                 skip "Need MDS version at least 2.12.54"
23497
23498         mkdir -p $DIR/$tdir
23499         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23500         createmany -o $DIR/$tdir/striped_dir/f 512
23501         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23502         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23503
23504         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23505                 sed "s/[/][^:]*://g")
23506
23507         rm -f $DIR/$tdir/striped_dir/f1*
23508         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23509         removed=$((512 - cnt))
23510
23511         # few files have been just removed, so we expect
23512         # rmfid to fail on their fids
23513         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23514         [ $removed != $errors ] && error "$errors != $removed"
23515
23516         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23517         rm -rf $DIR/$tdir
23518         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23519 }
23520 run_test 421g "rmfid to return errors properly"
23521
23522 test_422() {
23523         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23524         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23525         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23526         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23527         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23528
23529         local amc=$(at_max_get client)
23530         local amo=$(at_max_get mds1)
23531         local timeout=`lctl get_param -n timeout`
23532
23533         at_max_set 0 client
23534         at_max_set 0 mds1
23535
23536 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23537         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23538                         fail_val=$(((2*timeout + 10)*1000))
23539         touch $DIR/$tdir/d3/file &
23540         sleep 2
23541 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23542         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23543                         fail_val=$((2*timeout + 5))
23544         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23545         local pid=$!
23546         sleep 1
23547         kill -9 $pid
23548         sleep $((2 * timeout))
23549         echo kill $pid
23550         kill -9 $pid
23551         lctl mark touch
23552         touch $DIR/$tdir/d2/file3
23553         touch $DIR/$tdir/d2/file4
23554         touch $DIR/$tdir/d2/file5
23555
23556         wait
23557         at_max_set $amc client
23558         at_max_set $amo mds1
23559
23560         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23561         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23562                 error "Watchdog is always throttled"
23563 }
23564 run_test 422 "kill a process with RPC in progress"
23565
23566 stat_test() {
23567     df -h $MOUNT &
23568     df -h $MOUNT &
23569     df -h $MOUNT &
23570     df -h $MOUNT &
23571     df -h $MOUNT &
23572     df -h $MOUNT &
23573 }
23574
23575 test_423() {
23576     local _stats
23577     # ensure statfs cache is expired
23578     sleep 2;
23579
23580     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23581     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23582
23583     return 0
23584 }
23585 run_test 423 "statfs should return a right data"
23586
23587 test_424() {
23588 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23589         $LCTL set_param fail_loc=0x80000522
23590         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23591         rm -f $DIR/$tfile
23592 }
23593 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23594
23595 test_425() {
23596         test_mkdir -c -1 $DIR/$tdir
23597         $LFS setstripe -c -1 $DIR/$tdir
23598
23599         lru_resize_disable "" 100
23600         stack_trap "lru_resize_enable" EXIT
23601
23602         sleep 5
23603
23604         for i in $(seq $((MDSCOUNT * 125))); do
23605                 local t=$DIR/$tdir/$tfile_$i
23606
23607                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23608                         error_noexit "Create file $t"
23609         done
23610         stack_trap "rm -rf $DIR/$tdir" EXIT
23611
23612         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23613                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23614                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23615
23616                 [ $lock_count -le $lru_size ] ||
23617                         error "osc lock count $lock_count > lru size $lru_size"
23618         done
23619
23620         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23621                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23622                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23623
23624                 [ $lock_count -le $lru_size ] ||
23625                         error "mdc lock count $lock_count > lru size $lru_size"
23626         done
23627 }
23628 run_test 425 "lock count should not exceed lru size"
23629
23630 test_426() {
23631         splice-test -r $DIR/$tfile
23632         splice-test -rd $DIR/$tfile
23633         splice-test $DIR/$tfile
23634         splice-test -d $DIR/$tfile
23635 }
23636 run_test 426 "splice test on Lustre"
23637
23638 lseek_test_430() {
23639         local offset
23640         local file=$1
23641
23642         # data at [200K, 400K)
23643         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
23644                 error "256K->512K dd fails"
23645         # data at [2M, 3M)
23646         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
23647                 error "2M->3M dd fails"
23648         # data at [4M, 5M)
23649         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
23650                 error "4M->5M dd fails"
23651         echo "Data at 256K...512K, 2M...3M and 4M...5M"
23652         # start at first component hole #1
23653         printf "Seeking hole from 1000 ... "
23654         offset=$(lseek_test -l 1000 $file)
23655         echo $offset
23656         [[ $offset == 1000 ]] || error "offset $offset != 1000"
23657         printf "Seeking data from 1000 ... "
23658         offset=$(lseek_test -d 1000 $file)
23659         echo $offset
23660         [[ $offset == 262144 ]] || error "offset $offset != 262144"
23661
23662         # start at first component data block
23663         printf "Seeking hole from 300000 ... "
23664         offset=$(lseek_test -l 300000 $file)
23665         echo $offset
23666         [[ $offset == 524288 ]] || error "offset $offset != 524288"
23667         printf "Seeking data from 300000 ... "
23668         offset=$(lseek_test -d 300000 $file)
23669         echo $offset
23670         [[ $offset == 300000 ]] || error "offset $offset != 300000"
23671
23672         # start at the first component but beyond end of object size
23673         printf "Seeking hole from 1000000 ... "
23674         offset=$(lseek_test -l 1000000 $file)
23675         echo $offset
23676         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23677         printf "Seeking data from 1000000 ... "
23678         offset=$(lseek_test -d 1000000 $file)
23679         echo $offset
23680         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23681
23682         # start at second component stripe 2 (empty file)
23683         printf "Seeking hole from 1500000 ... "
23684         offset=$(lseek_test -l 1500000 $file)
23685         echo $offset
23686         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
23687         printf "Seeking data from 1500000 ... "
23688         offset=$(lseek_test -d 1500000 $file)
23689         echo $offset
23690         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23691
23692         # start at second component stripe 1 (all data)
23693         printf "Seeking hole from 3000000 ... "
23694         offset=$(lseek_test -l 3000000 $file)
23695         echo $offset
23696         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
23697         printf "Seeking data from 3000000 ... "
23698         offset=$(lseek_test -d 3000000 $file)
23699         echo $offset
23700         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
23701
23702         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
23703                 error "2nd dd fails"
23704         echo "Add data block at 640K...1280K"
23705
23706         # start at before new data block, in hole
23707         printf "Seeking hole from 600000 ... "
23708         offset=$(lseek_test -l 600000 $file)
23709         echo $offset
23710         [[ $offset == 600000 ]] || error "offset $offset != 600000"
23711         printf "Seeking data from 600000 ... "
23712         offset=$(lseek_test -d 600000 $file)
23713         echo $offset
23714         [[ $offset == 655360 ]] || error "offset $offset != 655360"
23715
23716         # start at the first component new data block
23717         printf "Seeking hole from 1000000 ... "
23718         offset=$(lseek_test -l 1000000 $file)
23719         echo $offset
23720         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23721         printf "Seeking data from 1000000 ... "
23722         offset=$(lseek_test -d 1000000 $file)
23723         echo $offset
23724         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23725
23726         # start at second component stripe 2, new data
23727         printf "Seeking hole from 1200000 ... "
23728         offset=$(lseek_test -l 1200000 $file)
23729         echo $offset
23730         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23731         printf "Seeking data from 1200000 ... "
23732         offset=$(lseek_test -d 1200000 $file)
23733         echo $offset
23734         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
23735
23736         # start beyond file end
23737         printf "Using offset > filesize ... "
23738         lseek_test -l 4000000 $file && error "lseek should fail"
23739         printf "Using offset > filesize ... "
23740         lseek_test -d 4000000 $file && error "lseek should fail"
23741
23742         printf "Done\n\n"
23743 }
23744
23745 test_430a() {
23746         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
23747                 skip "MDT does not support SEEK_HOLE"
23748
23749         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23750                 skip "OST does not support SEEK_HOLE"
23751
23752         local file=$DIR/$tdir/$tfile
23753
23754         mkdir -p $DIR/$tdir
23755
23756         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
23757         # OST stripe #1 will have continuous data at [1M, 3M)
23758         # OST stripe #2 is empty
23759         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
23760         lseek_test_430 $file
23761         rm $file
23762         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
23763         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
23764         lseek_test_430 $file
23765         rm $file
23766         $LFS setstripe -c2 -S 512K $file
23767         echo "Two stripes, stripe size 512K"
23768         lseek_test_430 $file
23769         rm $file
23770         # FLR with stale mirror
23771         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
23772                        -N -c2 -S 1M $file
23773         echo "Mirrored file:"
23774         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
23775         echo "Plain 2 stripes 1M"
23776         lseek_test_430 $file
23777         rm $file
23778 }
23779 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
23780
23781 test_430b() {
23782         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23783                 skip "OST does not support SEEK_HOLE"
23784
23785         local offset
23786         local file=$DIR/$tdir/$tfile
23787
23788         mkdir -p $DIR/$tdir
23789         # Empty layout lseek should fail
23790         $MCREATE $file
23791         # seek from 0
23792         printf "Seeking hole from 0 ... "
23793         lseek_test -l 0 $file && error "lseek should fail"
23794         printf "Seeking data from 0 ... "
23795         lseek_test -d 0 $file && error "lseek should fail"
23796         rm $file
23797
23798         # 1M-hole file
23799         $LFS setstripe -E 1M -c2 -E eof $file
23800         $TRUNCATE $file 1048576
23801         printf "Seeking hole from 1000000 ... "
23802         offset=$(lseek_test -l 1000000 $file)
23803         echo $offset
23804         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23805         printf "Seeking data from 1000000 ... "
23806         lseek_test -d 1000000 $file && error "lseek should fail"
23807         # full first component, non-inited second one
23808         dd if=/dev/urandom of=$file bs=1M count=1
23809         printf "Seeking hole from 1000000 ... "
23810         offset=$(lseek_test -l 1000000 $file)
23811         echo $offset
23812         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23813         printf "Seeking hole from 1048576 ... "
23814         lseek_test -l 1048576 $file && error "lseek should fail"
23815         # init second component and truncate back
23816         echo "123" >> $file
23817         $TRUNCATE $file 1048576
23818         ls -lia $file
23819         printf "Seeking hole from 1000000 ... "
23820         offset=$(lseek_test -l 1000000 $file)
23821         echo $offset
23822         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23823         printf "Seeking hole from 1048576 ... "
23824         lseek_test -l 1048576 $file && error "lseek should fail"
23825         # boundary checks for big values
23826         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
23827         offset=$(lseek_test -d 0 $file.10g)
23828         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
23829         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
23830         offset=$(lseek_test -d 0 $file.100g)
23831         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
23832         return 0
23833 }
23834 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
23835
23836 test_430c() {
23837         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23838                 skip "OST does not support SEEK_HOLE"
23839
23840         local file=$DIR/$tdir/$tfile
23841         local start
23842
23843         mkdir -p $DIR/$tdir
23844         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
23845
23846         # cp version 8.33+ prefers lseek over fiemap
23847         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
23848                 start=$SECONDS
23849                 time cp $file /dev/null
23850                 (( SECONDS - start < 5 )) ||
23851                         error "cp: too long runtime $((SECONDS - start))"
23852
23853         fi
23854         # tar version 1.29+ supports SEEK_HOLE/DATA
23855         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
23856                 start=$SECONDS
23857                 time tar cS $file - | cat > /dev/null
23858                 (( SECONDS - start < 5 )) ||
23859                         error "tar: too long runtime $((SECONDS - start))"
23860         fi
23861 }
23862 run_test 430c "lseek: external tools check"
23863
23864 prep_801() {
23865         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23866         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23867                 skip "Need server version at least 2.9.55"
23868
23869         start_full_debug_logging
23870 }
23871
23872 post_801() {
23873         stop_full_debug_logging
23874 }
23875
23876 barrier_stat() {
23877         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23878                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23879                            awk '/The barrier for/ { print $7 }')
23880                 echo $st
23881         else
23882                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23883                 echo \'$st\'
23884         fi
23885 }
23886
23887 barrier_expired() {
23888         local expired
23889
23890         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23891                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23892                           awk '/will be expired/ { print $7 }')
23893         else
23894                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23895         fi
23896
23897         echo $expired
23898 }
23899
23900 test_801a() {
23901         prep_801
23902
23903         echo "Start barrier_freeze at: $(date)"
23904         #define OBD_FAIL_BARRIER_DELAY          0x2202
23905         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23906         # Do not reduce barrier time - See LU-11873
23907         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23908
23909         sleep 2
23910         local b_status=$(barrier_stat)
23911         echo "Got barrier status at: $(date)"
23912         [ "$b_status" = "'freezing_p1'" ] ||
23913                 error "(1) unexpected barrier status $b_status"
23914
23915         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23916         wait
23917         b_status=$(barrier_stat)
23918         [ "$b_status" = "'frozen'" ] ||
23919                 error "(2) unexpected barrier status $b_status"
23920
23921         local expired=$(barrier_expired)
23922         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23923         sleep $((expired + 3))
23924
23925         b_status=$(barrier_stat)
23926         [ "$b_status" = "'expired'" ] ||
23927                 error "(3) unexpected barrier status $b_status"
23928
23929         # Do not reduce barrier time - See LU-11873
23930         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23931                 error "(4) fail to freeze barrier"
23932
23933         b_status=$(barrier_stat)
23934         [ "$b_status" = "'frozen'" ] ||
23935                 error "(5) unexpected barrier status $b_status"
23936
23937         echo "Start barrier_thaw at: $(date)"
23938         #define OBD_FAIL_BARRIER_DELAY          0x2202
23939         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23940         do_facet mgs $LCTL barrier_thaw $FSNAME &
23941
23942         sleep 2
23943         b_status=$(barrier_stat)
23944         echo "Got barrier status at: $(date)"
23945         [ "$b_status" = "'thawing'" ] ||
23946                 error "(6) unexpected barrier status $b_status"
23947
23948         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23949         wait
23950         b_status=$(barrier_stat)
23951         [ "$b_status" = "'thawed'" ] ||
23952                 error "(7) unexpected barrier status $b_status"
23953
23954         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23955         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23956         do_facet mgs $LCTL barrier_freeze $FSNAME
23957
23958         b_status=$(barrier_stat)
23959         [ "$b_status" = "'failed'" ] ||
23960                 error "(8) unexpected barrier status $b_status"
23961
23962         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23963         do_facet mgs $LCTL barrier_thaw $FSNAME
23964
23965         post_801
23966 }
23967 run_test 801a "write barrier user interfaces and stat machine"
23968
23969 test_801b() {
23970         prep_801
23971
23972         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23973         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23974         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23975         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23976         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23977
23978         cancel_lru_locks mdc
23979
23980         # 180 seconds should be long enough
23981         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23982
23983         local b_status=$(barrier_stat)
23984         [ "$b_status" = "'frozen'" ] ||
23985                 error "(6) unexpected barrier status $b_status"
23986
23987         mkdir $DIR/$tdir/d0/d10 &
23988         mkdir_pid=$!
23989
23990         touch $DIR/$tdir/d1/f13 &
23991         touch_pid=$!
23992
23993         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23994         ln_pid=$!
23995
23996         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23997         mv_pid=$!
23998
23999         rm -f $DIR/$tdir/d4/f12 &
24000         rm_pid=$!
24001
24002         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24003
24004         # To guarantee taht the 'stat' is not blocked
24005         b_status=$(barrier_stat)
24006         [ "$b_status" = "'frozen'" ] ||
24007                 error "(8) unexpected barrier status $b_status"
24008
24009         # let above commands to run at background
24010         sleep 5
24011
24012         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24013         ps -p $touch_pid || error "(10) touch should be blocked"
24014         ps -p $ln_pid || error "(11) link should be blocked"
24015         ps -p $mv_pid || error "(12) rename should be blocked"
24016         ps -p $rm_pid || error "(13) unlink should be blocked"
24017
24018         b_status=$(barrier_stat)
24019         [ "$b_status" = "'frozen'" ] ||
24020                 error "(14) unexpected barrier status $b_status"
24021
24022         do_facet mgs $LCTL barrier_thaw $FSNAME
24023         b_status=$(barrier_stat)
24024         [ "$b_status" = "'thawed'" ] ||
24025                 error "(15) unexpected barrier status $b_status"
24026
24027         wait $mkdir_pid || error "(16) mkdir should succeed"
24028         wait $touch_pid || error "(17) touch should succeed"
24029         wait $ln_pid || error "(18) link should succeed"
24030         wait $mv_pid || error "(19) rename should succeed"
24031         wait $rm_pid || error "(20) unlink should succeed"
24032
24033         post_801
24034 }
24035 run_test 801b "modification will be blocked by write barrier"
24036
24037 test_801c() {
24038         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24039
24040         prep_801
24041
24042         stop mds2 || error "(1) Fail to stop mds2"
24043
24044         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24045
24046         local b_status=$(barrier_stat)
24047         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24048                 do_facet mgs $LCTL barrier_thaw $FSNAME
24049                 error "(2) unexpected barrier status $b_status"
24050         }
24051
24052         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24053                 error "(3) Fail to rescan barrier bitmap"
24054
24055         # Do not reduce barrier time - See LU-11873
24056         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24057
24058         b_status=$(barrier_stat)
24059         [ "$b_status" = "'frozen'" ] ||
24060                 error "(4) unexpected barrier status $b_status"
24061
24062         do_facet mgs $LCTL barrier_thaw $FSNAME
24063         b_status=$(barrier_stat)
24064         [ "$b_status" = "'thawed'" ] ||
24065                 error "(5) unexpected barrier status $b_status"
24066
24067         local devname=$(mdsdevname 2)
24068
24069         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24070
24071         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24072                 error "(7) Fail to rescan barrier bitmap"
24073
24074         post_801
24075 }
24076 run_test 801c "rescan barrier bitmap"
24077
24078 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24079 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24080 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24081 saved_MOUNT_OPTS=$MOUNT_OPTS
24082
24083 cleanup_802a() {
24084         trap 0
24085
24086         stopall
24087         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24088         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24089         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24090         MOUNT_OPTS=$saved_MOUNT_OPTS
24091         setupall
24092 }
24093
24094 test_802a() {
24095         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24096         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24097         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24098                 skip "Need server version at least 2.9.55"
24099
24100         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24101
24102         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24103
24104         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24105                 error "(2) Fail to copy"
24106
24107         trap cleanup_802a EXIT
24108
24109         # sync by force before remount as readonly
24110         sync; sync_all_data; sleep 3; sync_all_data
24111
24112         stopall
24113
24114         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24115         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24116         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24117
24118         echo "Mount the server as read only"
24119         setupall server_only || error "(3) Fail to start servers"
24120
24121         echo "Mount client without ro should fail"
24122         mount_client $MOUNT &&
24123                 error "(4) Mount client without 'ro' should fail"
24124
24125         echo "Mount client with ro should succeed"
24126         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24127         mount_client $MOUNT ||
24128                 error "(5) Mount client with 'ro' should succeed"
24129
24130         echo "Modify should be refused"
24131         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24132
24133         echo "Read should be allowed"
24134         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24135                 error "(7) Read should succeed under ro mode"
24136
24137         cleanup_802a
24138 }
24139 run_test 802a "simulate readonly device"
24140
24141 test_802b() {
24142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24143         remote_mds_nodsh && skip "remote MDS with nodsh"
24144
24145         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24146                 skip "readonly option not available"
24147
24148         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24149
24150         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24151                 error "(2) Fail to copy"
24152
24153         # write back all cached data before setting MDT to readonly
24154         cancel_lru_locks
24155         sync_all_data
24156
24157         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24158         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24159
24160         echo "Modify should be refused"
24161         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24162
24163         echo "Read should be allowed"
24164         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24165                 error "(7) Read should succeed under ro mode"
24166
24167         # disable readonly
24168         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24169 }
24170 run_test 802b "be able to set MDTs to readonly"
24171
24172 test_803a() {
24173         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24174         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24175                 skip "MDS needs to be newer than 2.10.54"
24176
24177         mkdir -p $DIR/$tdir
24178         # Create some objects on all MDTs to trigger related logs objects
24179         for idx in $(seq $MDSCOUNT); do
24180                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24181                         $DIR/$tdir/dir${idx} ||
24182                         error "Fail to create $DIR/$tdir/dir${idx}"
24183         done
24184
24185         sync; sleep 3
24186         wait_delete_completed # ensure old test cleanups are finished
24187         echo "before create:"
24188         $LFS df -i $MOUNT
24189         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24190
24191         for i in {1..10}; do
24192                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24193                         error "Fail to create $DIR/$tdir/foo$i"
24194         done
24195
24196         sync; sleep 3
24197         echo "after create:"
24198         $LFS df -i $MOUNT
24199         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24200
24201         # allow for an llog to be cleaned up during the test
24202         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24203                 error "before ($before_used) + 10 > after ($after_used)"
24204
24205         for i in {1..10}; do
24206                 rm -rf $DIR/$tdir/foo$i ||
24207                         error "Fail to remove $DIR/$tdir/foo$i"
24208         done
24209
24210         sleep 3 # avoid MDT return cached statfs
24211         wait_delete_completed
24212         echo "after unlink:"
24213         $LFS df -i $MOUNT
24214         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24215
24216         # allow for an llog to be created during the test
24217         [ $after_used -le $((before_used + 1)) ] ||
24218                 error "after ($after_used) > before ($before_used) + 1"
24219 }
24220 run_test 803a "verify agent object for remote object"
24221
24222 test_803b() {
24223         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24224         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24225                 skip "MDS needs to be newer than 2.13.56"
24226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24227
24228         for i in $(seq 0 $((MDSCOUNT - 1))); do
24229                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24230         done
24231
24232         local before=0
24233         local after=0
24234
24235         local tmp
24236
24237         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24238         for i in $(seq 0 $((MDSCOUNT - 1))); do
24239                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24240                         awk '/getattr/ { print $2 }')
24241                 before=$((before + tmp))
24242         done
24243         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24244         for i in $(seq 0 $((MDSCOUNT - 1))); do
24245                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24246                         awk '/getattr/ { print $2 }')
24247                 after=$((after + tmp))
24248         done
24249
24250         [ $before -eq $after ] || error "getattr count $before != $after"
24251 }
24252 run_test 803b "remote object can getattr from cache"
24253
24254 test_804() {
24255         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24256         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24257                 skip "MDS needs to be newer than 2.10.54"
24258         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24259
24260         mkdir -p $DIR/$tdir
24261         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24262                 error "Fail to create $DIR/$tdir/dir0"
24263
24264         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24265         local dev=$(mdsdevname 2)
24266
24267         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24268                 grep ${fid} || error "NOT found agent entry for dir0"
24269
24270         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24271                 error "Fail to create $DIR/$tdir/dir1"
24272
24273         touch $DIR/$tdir/dir1/foo0 ||
24274                 error "Fail to create $DIR/$tdir/dir1/foo0"
24275         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24276         local rc=0
24277
24278         for idx in $(seq $MDSCOUNT); do
24279                 dev=$(mdsdevname $idx)
24280                 do_facet mds${idx} \
24281                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24282                         grep ${fid} && rc=$idx
24283         done
24284
24285         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24286                 error "Fail to rename foo0 to foo1"
24287         if [ $rc -eq 0 ]; then
24288                 for idx in $(seq $MDSCOUNT); do
24289                         dev=$(mdsdevname $idx)
24290                         do_facet mds${idx} \
24291                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24292                         grep ${fid} && rc=$idx
24293                 done
24294         fi
24295
24296         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24297                 error "Fail to rename foo1 to foo2"
24298         if [ $rc -eq 0 ]; then
24299                 for idx in $(seq $MDSCOUNT); do
24300                         dev=$(mdsdevname $idx)
24301                         do_facet mds${idx} \
24302                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24303                         grep ${fid} && rc=$idx
24304                 done
24305         fi
24306
24307         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24308
24309         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24310                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24311         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24312                 error "Fail to rename foo2 to foo0"
24313         unlink $DIR/$tdir/dir1/foo0 ||
24314                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24315         rm -rf $DIR/$tdir/dir0 ||
24316                 error "Fail to rm $DIR/$tdir/dir0"
24317
24318         for idx in $(seq $MDSCOUNT); do
24319                 dev=$(mdsdevname $idx)
24320                 rc=0
24321
24322                 stop mds${idx}
24323                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24324                         rc=$?
24325                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24326                         error "mount mds$idx failed"
24327                 df $MOUNT > /dev/null 2>&1
24328
24329                 # e2fsck should not return error
24330                 [ $rc -eq 0 ] ||
24331                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24332         done
24333 }
24334 run_test 804 "verify agent entry for remote entry"
24335
24336 cleanup_805() {
24337         do_facet $SINGLEMDS zfs set quota=$old $fsset
24338         unlinkmany $DIR/$tdir/f- 1000000
24339         trap 0
24340 }
24341
24342 test_805() {
24343         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24344         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24345         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24346                 skip "netfree not implemented before 0.7"
24347         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24348                 skip "Need MDS version at least 2.10.57"
24349
24350         local fsset
24351         local freekb
24352         local usedkb
24353         local old
24354         local quota
24355         local pref="osd-zfs.$FSNAME-MDT0000."
24356
24357         # limit available space on MDS dataset to meet nospace issue
24358         # quickly. then ZFS 0.7.2 can use reserved space if asked
24359         # properly (using netfree flag in osd_declare_destroy()
24360         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24361         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24362                 gawk '{print $3}')
24363         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24364         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24365         let "usedkb=usedkb-freekb"
24366         let "freekb=freekb/2"
24367         if let "freekb > 5000"; then
24368                 let "freekb=5000"
24369         fi
24370         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24371         trap cleanup_805 EXIT
24372         mkdir $DIR/$tdir
24373         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24374                 error "Can't set PFL layout"
24375         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24376         rm -rf $DIR/$tdir || error "not able to remove"
24377         do_facet $SINGLEMDS zfs set quota=$old $fsset
24378         trap 0
24379 }
24380 run_test 805 "ZFS can remove from full fs"
24381
24382 # Size-on-MDS test
24383 check_lsom_data()
24384 {
24385         local file=$1
24386         local size=$($LFS getsom -s $file)
24387         local expect=$(stat -c %s $file)
24388
24389         [[ $size == $expect ]] ||
24390                 error "$file expected size: $expect, got: $size"
24391
24392         local blocks=$($LFS getsom -b $file)
24393         expect=$(stat -c %b $file)
24394         [[ $blocks == $expect ]] ||
24395                 error "$file expected blocks: $expect, got: $blocks"
24396 }
24397
24398 check_lsom_size()
24399 {
24400         local size=$($LFS getsom -s $1)
24401         local expect=$2
24402
24403         [[ $size == $expect ]] ||
24404                 error "$file expected size: $expect, got: $size"
24405 }
24406
24407 test_806() {
24408         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24409                 skip "Need MDS version at least 2.11.52"
24410
24411         local bs=1048576
24412
24413         touch $DIR/$tfile || error "touch $tfile failed"
24414
24415         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24416         save_lustre_params client "llite.*.xattr_cache" > $save
24417         lctl set_param llite.*.xattr_cache=0
24418         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24419
24420         # single-threaded write
24421         echo "Test SOM for single-threaded write"
24422         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24423                 error "write $tfile failed"
24424         check_lsom_size $DIR/$tfile $bs
24425
24426         local num=32
24427         local size=$(($num * $bs))
24428         local offset=0
24429         local i
24430
24431         echo "Test SOM for single client multi-threaded($num) write"
24432         $TRUNCATE $DIR/$tfile 0
24433         for ((i = 0; i < $num; i++)); do
24434                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24435                 local pids[$i]=$!
24436                 offset=$((offset + $bs))
24437         done
24438         for (( i=0; i < $num; i++ )); do
24439                 wait ${pids[$i]}
24440         done
24441         check_lsom_size $DIR/$tfile $size
24442
24443         $TRUNCATE $DIR/$tfile 0
24444         for ((i = 0; i < $num; i++)); do
24445                 offset=$((offset - $bs))
24446                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24447                 local pids[$i]=$!
24448         done
24449         for (( i=0; i < $num; i++ )); do
24450                 wait ${pids[$i]}
24451         done
24452         check_lsom_size $DIR/$tfile $size
24453
24454         # multi-client writes
24455         num=$(get_node_count ${CLIENTS//,/ })
24456         size=$(($num * $bs))
24457         offset=0
24458         i=0
24459
24460         echo "Test SOM for multi-client ($num) writes"
24461         $TRUNCATE $DIR/$tfile 0
24462         for client in ${CLIENTS//,/ }; do
24463                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24464                 local pids[$i]=$!
24465                 i=$((i + 1))
24466                 offset=$((offset + $bs))
24467         done
24468         for (( i=0; i < $num; i++ )); do
24469                 wait ${pids[$i]}
24470         done
24471         check_lsom_size $DIR/$tfile $offset
24472
24473         i=0
24474         $TRUNCATE $DIR/$tfile 0
24475         for client in ${CLIENTS//,/ }; do
24476                 offset=$((offset - $bs))
24477                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24478                 local pids[$i]=$!
24479                 i=$((i + 1))
24480         done
24481         for (( i=0; i < $num; i++ )); do
24482                 wait ${pids[$i]}
24483         done
24484         check_lsom_size $DIR/$tfile $size
24485
24486         # verify truncate
24487         echo "Test SOM for truncate"
24488         $TRUNCATE $DIR/$tfile 1048576
24489         check_lsom_size $DIR/$tfile 1048576
24490         $TRUNCATE $DIR/$tfile 1234
24491         check_lsom_size $DIR/$tfile 1234
24492
24493         # verify SOM blocks count
24494         echo "Verify SOM block count"
24495         $TRUNCATE $DIR/$tfile 0
24496         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24497                 error "failed to write file $tfile"
24498         check_lsom_data $DIR/$tfile
24499 }
24500 run_test 806 "Verify Lazy Size on MDS"
24501
24502 test_807() {
24503         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24504         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24505                 skip "Need MDS version at least 2.11.52"
24506
24507         # Registration step
24508         changelog_register || error "changelog_register failed"
24509         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24510         changelog_users $SINGLEMDS | grep -q $cl_user ||
24511                 error "User $cl_user not found in changelog_users"
24512
24513         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24514         save_lustre_params client "llite.*.xattr_cache" > $save
24515         lctl set_param llite.*.xattr_cache=0
24516         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24517
24518         rm -rf $DIR/$tdir || error "rm $tdir failed"
24519         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24520         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24521         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24522         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24523                 error "truncate $tdir/trunc failed"
24524
24525         local bs=1048576
24526         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24527                 error "write $tfile failed"
24528
24529         # multi-client wirtes
24530         local num=$(get_node_count ${CLIENTS//,/ })
24531         local offset=0
24532         local i=0
24533
24534         echo "Test SOM for multi-client ($num) writes"
24535         touch $DIR/$tfile || error "touch $tfile failed"
24536         $TRUNCATE $DIR/$tfile 0
24537         for client in ${CLIENTS//,/ }; do
24538                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24539                 local pids[$i]=$!
24540                 i=$((i + 1))
24541                 offset=$((offset + $bs))
24542         done
24543         for (( i=0; i < $num; i++ )); do
24544                 wait ${pids[$i]}
24545         done
24546
24547         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24548         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24549         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24550         check_lsom_data $DIR/$tdir/trunc
24551         check_lsom_data $DIR/$tdir/single_dd
24552         check_lsom_data $DIR/$tfile
24553
24554         rm -rf $DIR/$tdir
24555         # Deregistration step
24556         changelog_deregister || error "changelog_deregister failed"
24557 }
24558 run_test 807 "verify LSOM syncing tool"
24559
24560 check_som_nologged()
24561 {
24562         local lines=$($LFS changelog $FSNAME-MDT0000 |
24563                 grep 'x=trusted.som' | wc -l)
24564         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24565 }
24566
24567 test_808() {
24568         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24569                 skip "Need MDS version at least 2.11.55"
24570
24571         # Registration step
24572         changelog_register || error "changelog_register failed"
24573
24574         touch $DIR/$tfile || error "touch $tfile failed"
24575         check_som_nologged
24576
24577         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24578                 error "write $tfile failed"
24579         check_som_nologged
24580
24581         $TRUNCATE $DIR/$tfile 1234
24582         check_som_nologged
24583
24584         $TRUNCATE $DIR/$tfile 1048576
24585         check_som_nologged
24586
24587         # Deregistration step
24588         changelog_deregister || error "changelog_deregister failed"
24589 }
24590 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24591
24592 check_som_nodata()
24593 {
24594         $LFS getsom $1
24595         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24596 }
24597
24598 test_809() {
24599         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24600                 skip "Need MDS version at least 2.11.56"
24601
24602         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24603                 error "failed to create DoM-only file $DIR/$tfile"
24604         touch $DIR/$tfile || error "touch $tfile failed"
24605         check_som_nodata $DIR/$tfile
24606
24607         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24608                 error "write $tfile failed"
24609         check_som_nodata $DIR/$tfile
24610
24611         $TRUNCATE $DIR/$tfile 1234
24612         check_som_nodata $DIR/$tfile
24613
24614         $TRUNCATE $DIR/$tfile 4097
24615         check_som_nodata $DIR/$file
24616 }
24617 run_test 809 "Verify no SOM xattr store for DoM-only files"
24618
24619 test_810() {
24620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24621         $GSS && skip_env "could not run with gss"
24622         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24623                 skip "OST < 2.12.58 doesn't align checksum"
24624
24625         set_checksums 1
24626         stack_trap "set_checksums $ORIG_CSUM" EXIT
24627         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24628
24629         local csum
24630         local before
24631         local after
24632         for csum in $CKSUM_TYPES; do
24633                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24634                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24635                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24636                         eval set -- $i
24637                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24638                         before=$(md5sum $DIR/$tfile)
24639                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24640                         after=$(md5sum $DIR/$tfile)
24641                         [ "$before" == "$after" ] ||
24642                                 error "$csum: $before != $after bs=$1 seek=$2"
24643                 done
24644         done
24645 }
24646 run_test 810 "partial page writes on ZFS (LU-11663)"
24647
24648 test_812a() {
24649         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24650                 skip "OST < 2.12.51 doesn't support this fail_loc"
24651
24652         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24653         # ensure ost1 is connected
24654         stat $DIR/$tfile >/dev/null || error "can't stat"
24655         wait_osc_import_state client ost1 FULL
24656         # no locks, no reqs to let the connection idle
24657         cancel_lru_locks osc
24658
24659         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24660 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24661         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24662         wait_osc_import_state client ost1 CONNECTING
24663         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24664
24665         stat $DIR/$tfile >/dev/null || error "can't stat file"
24666 }
24667 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24668
24669 test_812b() { # LU-12378
24670         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24671                 skip "OST < 2.12.51 doesn't support this fail_loc"
24672
24673         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24674         # ensure ost1 is connected
24675         stat $DIR/$tfile >/dev/null || error "can't stat"
24676         wait_osc_import_state client ost1 FULL
24677         # no locks, no reqs to let the connection idle
24678         cancel_lru_locks osc
24679
24680         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24681 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24682         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24683         wait_osc_import_state client ost1 CONNECTING
24684         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24685
24686         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24687         wait_osc_import_state client ost1 IDLE
24688 }
24689 run_test 812b "do not drop no resend request for idle connect"
24690
24691 test_813() {
24692         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24693         [ -z "$file_heat_sav" ] && skip "no file heat support"
24694
24695         local readsample
24696         local writesample
24697         local readbyte
24698         local writebyte
24699         local readsample1
24700         local writesample1
24701         local readbyte1
24702         local writebyte1
24703
24704         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24705         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24706
24707         $LCTL set_param -n llite.*.file_heat=1
24708         echo "Turn on file heat"
24709         echo "Period second: $period_second, Decay percentage: $decay_pct"
24710
24711         echo "QQQQ" > $DIR/$tfile
24712         echo "QQQQ" > $DIR/$tfile
24713         echo "QQQQ" > $DIR/$tfile
24714         cat $DIR/$tfile > /dev/null
24715         cat $DIR/$tfile > /dev/null
24716         cat $DIR/$tfile > /dev/null
24717         cat $DIR/$tfile > /dev/null
24718
24719         local out=$($LFS heat_get $DIR/$tfile)
24720
24721         $LFS heat_get $DIR/$tfile
24722         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24723         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24724         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24725         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24726
24727         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24728         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24729         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24730         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24731
24732         sleep $((period_second + 3))
24733         echo "Sleep $((period_second + 3)) seconds..."
24734         # The recursion formula to calculate the heat of the file f is as
24735         # follow:
24736         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24737         # Where Hi is the heat value in the period between time points i*I and
24738         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24739         # to the weight of Ci.
24740         out=$($LFS heat_get $DIR/$tfile)
24741         $LFS heat_get $DIR/$tfile
24742         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24743         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24744         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24745         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24746
24747         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24748                 error "read sample ($readsample) is wrong"
24749         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24750                 error "write sample ($writesample) is wrong"
24751         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24752                 error "read bytes ($readbyte) is wrong"
24753         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24754                 error "write bytes ($writebyte) is wrong"
24755
24756         echo "QQQQ" > $DIR/$tfile
24757         echo "QQQQ" > $DIR/$tfile
24758         echo "QQQQ" > $DIR/$tfile
24759         cat $DIR/$tfile > /dev/null
24760         cat $DIR/$tfile > /dev/null
24761         cat $DIR/$tfile > /dev/null
24762         cat $DIR/$tfile > /dev/null
24763
24764         sleep $((period_second + 3))
24765         echo "Sleep $((period_second + 3)) seconds..."
24766
24767         out=$($LFS heat_get $DIR/$tfile)
24768         $LFS heat_get $DIR/$tfile
24769         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24770         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24771         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24772         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24773
24774         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24775                 4 * $decay_pct) / 100") -eq 1 ] ||
24776                 error "read sample ($readsample1) is wrong"
24777         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24778                 3 * $decay_pct) / 100") -eq 1 ] ||
24779                 error "write sample ($writesample1) is wrong"
24780         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24781                 20 * $decay_pct) / 100") -eq 1 ] ||
24782                 error "read bytes ($readbyte1) is wrong"
24783         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24784                 15 * $decay_pct) / 100") -eq 1 ] ||
24785                 error "write bytes ($writebyte1) is wrong"
24786
24787         echo "Turn off file heat for the file $DIR/$tfile"
24788         $LFS heat_set -o $DIR/$tfile
24789
24790         echo "QQQQ" > $DIR/$tfile
24791         echo "QQQQ" > $DIR/$tfile
24792         echo "QQQQ" > $DIR/$tfile
24793         cat $DIR/$tfile > /dev/null
24794         cat $DIR/$tfile > /dev/null
24795         cat $DIR/$tfile > /dev/null
24796         cat $DIR/$tfile > /dev/null
24797
24798         out=$($LFS heat_get $DIR/$tfile)
24799         $LFS heat_get $DIR/$tfile
24800         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24801         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24802         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24803         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24804
24805         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24806         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24807         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24808         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24809
24810         echo "Trun on file heat for the file $DIR/$tfile"
24811         $LFS heat_set -O $DIR/$tfile
24812
24813         echo "QQQQ" > $DIR/$tfile
24814         echo "QQQQ" > $DIR/$tfile
24815         echo "QQQQ" > $DIR/$tfile
24816         cat $DIR/$tfile > /dev/null
24817         cat $DIR/$tfile > /dev/null
24818         cat $DIR/$tfile > /dev/null
24819         cat $DIR/$tfile > /dev/null
24820
24821         out=$($LFS heat_get $DIR/$tfile)
24822         $LFS heat_get $DIR/$tfile
24823         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24824         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24825         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24826         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24827
24828         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24829         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24830         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24831         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24832
24833         $LFS heat_set -c $DIR/$tfile
24834         $LCTL set_param -n llite.*.file_heat=0
24835         echo "Turn off file heat support for the Lustre filesystem"
24836
24837         echo "QQQQ" > $DIR/$tfile
24838         echo "QQQQ" > $DIR/$tfile
24839         echo "QQQQ" > $DIR/$tfile
24840         cat $DIR/$tfile > /dev/null
24841         cat $DIR/$tfile > /dev/null
24842         cat $DIR/$tfile > /dev/null
24843         cat $DIR/$tfile > /dev/null
24844
24845         out=$($LFS heat_get $DIR/$tfile)
24846         $LFS heat_get $DIR/$tfile
24847         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24848         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24849         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24850         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24851
24852         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24853         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24854         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24855         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24856
24857         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24858         rm -f $DIR/$tfile
24859 }
24860 run_test 813 "File heat verfication"
24861
24862 test_814()
24863 {
24864         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24865         echo -n y >> $DIR/$tfile
24866         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24867         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24868 }
24869 run_test 814 "sparse cp works as expected (LU-12361)"
24870
24871 test_815()
24872 {
24873         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24874         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24875 }
24876 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24877
24878 test_816() {
24879         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24880         # ensure ost1 is connected
24881         stat $DIR/$tfile >/dev/null || error "can't stat"
24882         wait_osc_import_state client ost1 FULL
24883         # no locks, no reqs to let the connection idle
24884         cancel_lru_locks osc
24885         lru_resize_disable osc
24886         local before
24887         local now
24888         before=$($LCTL get_param -n \
24889                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24890
24891         wait_osc_import_state client ost1 IDLE
24892         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24893         now=$($LCTL get_param -n \
24894               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24895         [ $before == $now ] || error "lru_size changed $before != $now"
24896 }
24897 run_test 816 "do not reset lru_resize on idle reconnect"
24898
24899 cleanup_817() {
24900         umount $tmpdir
24901         exportfs -u localhost:$DIR/nfsexp
24902         rm -rf $DIR/nfsexp
24903 }
24904
24905 test_817() {
24906         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24907
24908         mkdir -p $DIR/nfsexp
24909         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24910                 error "failed to export nfs"
24911
24912         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24913         stack_trap cleanup_817 EXIT
24914
24915         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24916                 error "failed to mount nfs to $tmpdir"
24917
24918         cp /bin/true $tmpdir
24919         $DIR/nfsexp/true || error "failed to execute 'true' command"
24920 }
24921 run_test 817 "nfsd won't cache write lock for exec file"
24922
24923 test_818() {
24924         mkdir $DIR/$tdir
24925         $LFS setstripe -c1 -i0 $DIR/$tfile
24926         $LFS setstripe -c1 -i1 $DIR/$tfile
24927         stop $SINGLEMDS
24928         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24929         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24930         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24931                 error "start $SINGLEMDS failed"
24932         rm -rf $DIR/$tdir
24933 }
24934 run_test 818 "unlink with failed llog"
24935
24936 test_819a() {
24937         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24938         cancel_lru_locks osc
24939         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24940         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24941         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24942         rm -f $TDIR/$tfile
24943 }
24944 run_test 819a "too big niobuf in read"
24945
24946 test_819b() {
24947         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24948         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24949         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24950         cancel_lru_locks osc
24951         sleep 1
24952         rm -f $TDIR/$tfile
24953 }
24954 run_test 819b "too big niobuf in write"
24955
24956
24957 function test_820_start_ost() {
24958         sleep 5
24959
24960         for num in $(seq $OSTCOUNT); do
24961                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24962         done
24963 }
24964
24965 test_820() {
24966         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24967
24968         mkdir $DIR/$tdir
24969         umount_client $MOUNT || error "umount failed"
24970         for num in $(seq $OSTCOUNT); do
24971                 stop ost$num
24972         done
24973
24974         # mount client with no active OSTs
24975         # so that the client can't initialize max LOV EA size
24976         # from OSC notifications
24977         mount_client $MOUNT || error "mount failed"
24978         # delay OST starting to keep this 0 max EA size for a while
24979         test_820_start_ost &
24980
24981         # create a directory on MDS2
24982         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24983                 error "Failed to create directory"
24984         # open intent should update default EA size
24985         # see mdc_update_max_ea_from_body()
24986         # notice this is the very first RPC to MDS2
24987         cp /etc/services $DIR/$tdir/mds2 ||
24988                 error "Failed to copy files to mds$n"
24989 }
24990 run_test 820 "update max EA from open intent"
24991
24992 #
24993 # tests that do cleanup/setup should be run at the end
24994 #
24995
24996 test_900() {
24997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24998         local ls
24999
25000         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25001         $LCTL set_param fail_loc=0x903
25002
25003         cancel_lru_locks MGC
25004
25005         FAIL_ON_ERROR=true cleanup
25006         FAIL_ON_ERROR=true setup
25007 }
25008 run_test 900 "umount should not race with any mgc requeue thread"
25009
25010 # LUS-6253/LU-11185
25011 test_901() {
25012         local oldc
25013         local newc
25014         local olds
25015         local news
25016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25017
25018         # some get_param have a bug to handle dot in param name
25019         cancel_lru_locks MGC
25020         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25021         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25022         umount_client $MOUNT || error "umount failed"
25023         mount_client $MOUNT || error "mount failed"
25024         cancel_lru_locks MGC
25025         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25026         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25027
25028         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25029         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25030
25031         return 0
25032 }
25033 run_test 901 "don't leak a mgc lock on client umount"
25034
25035 # LU-13377
25036 test_902() {
25037         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25038                 skip "client does not have LU-13377 fix"
25039         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25040         $LCTL set_param fail_loc=0x1415
25041         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25042         cancel_lru_locks osc
25043         rm -f $DIR/$tfile
25044 }
25045 run_test 902 "test short write doesn't hang lustre"
25046
25047 complete $SECONDS
25048 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25049 check_and_cleanup_lustre
25050 if [ "$I_MOUNTED" != "yes" ]; then
25051         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25052 fi
25053 exit_status