Whamcloud - gitweb
579f2bd0384fcb3853a6054d0e1fd88d66d2897b
[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 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5              12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 # Get the SLES distro version
96 #
97 # Returns a version string that should only be used in comparing
98 # strings returned by version_code()
99 sles_version_code()
100 {
101         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
102
103         # All SuSE Linux versions have one decimal. version_code expects two
104         local sles_version=$version.0
105         version_code $sles_version
106 }
107
108 # Check if we are running on Ubuntu or SLES so we can make decisions on
109 # what tests to run
110 if [ -r /etc/SuSE-release ]; then
111         sles_version=$(sles_version_code)
112         [ $sles_version -lt $(version_code 11.4.0) ] &&
113                 # bug number for skipped test: LU-4341
114                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
115         [ $sles_version -lt $(version_code 12.0.0) ] &&
116                 # bug number for skipped test: LU-3703
117                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
118 elif [ -r /etc/os-release ]; then
119         if grep -qi ubuntu /etc/os-release; then
120                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
121                                                 -e 's/^VERSION=//p' \
122                                                 /etc/os-release |
123                                                 awk '{ print $1 }'))
124
125                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
126                         # bug number for skipped test:
127                         #                LU-10334 LU-10366
128                         ALWAYS_EXCEPT+=" 103a     410"
129                 fi
130         fi
131 fi
132
133 build_test_filter
134 FAIL_ON_ERROR=false
135
136 cleanup() {
137         echo -n "cln.."
138         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
139         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
140 }
141 setup() {
142         echo -n "mnt.."
143         load_modules
144         setupall || exit 10
145         echo "done"
146 }
147
148 check_swap_layouts_support()
149 {
150         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
151                 skip "Does not support layout lock."
152 }
153
154 check_swap_layout_no_dom()
155 {
156         local FOLDER=$1
157         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
158         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
159 }
160
161 check_and_setup_lustre
162 DIR=${DIR:-$MOUNT}
163 assert_DIR
164
165 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
166
167 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
168 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
169 rm -rf $DIR/[Rdfs][0-9]*
170
171 # $RUNAS_ID may get set incorrectly somewhere else
172 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
173         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
174
175 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
176
177 if [ "${ONLY}" = "MOUNT" ] ; then
178         echo "Lustre is up, please go on"
179         exit
180 fi
181
182 echo "preparing for tests involving mounts"
183 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
184 touch $EXT2_DEV
185 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
186 echo # add a newline after mke2fs.
187
188 umask 077
189
190 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
191 lctl set_param debug=-1 2> /dev/null || true
192 test_0a() {
193         touch $DIR/$tfile
194         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
195         rm $DIR/$tfile
196         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
197 }
198 run_test 0a "touch; rm ====================="
199
200 test_0b() {
201         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
202         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
203 }
204 run_test 0b "chmod 0755 $DIR ============================="
205
206 test_0c() {
207         $LCTL get_param mdc.*.import | grep "state: FULL" ||
208                 error "import not FULL"
209         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
210                 error "bad target"
211 }
212 run_test 0c "check import proc"
213
214 test_0d() { # LU-3397
215         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
216                 skip "proc exports not supported before 2.10.57"
217
218         local mgs_exp="mgs.MGS.exports"
219         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
220         local exp_client_nid
221         local exp_client_version
222         local exp_val
223         local imp_val
224         local temp_imp=$DIR/$tfile.import
225         local temp_exp=$DIR/$tfile.export
226
227         # save mgc import file to $temp_imp
228         $LCTL get_param mgc.*.import | tee $temp_imp
229         # Check if client uuid is found in MGS export
230         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
231                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
232                         $client_uuid ] &&
233                         break;
234         done
235         # save mgs export file to $temp_exp
236         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
237
238         # Compare the value of field "connect_flags"
239         imp_val=$(grep "connect_flags" $temp_imp)
240         exp_val=$(grep "connect_flags" $temp_exp)
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export flags '$exp_val' != import flags '$imp_val'"
243
244         # Compare client versions.  Only compare top-3 fields for compatibility
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
247         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "exp version '$exp_client_version'($exp_val) != " \
250                         "'$(lustre_build_version client)'($imp_val)"
251 }
252 run_test 0d "check export proc ============================="
253
254 test_1() {
255         test_mkdir $DIR/$tdir
256         test_mkdir $DIR/$tdir/d2
257         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
258         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
259         rmdir $DIR/$tdir/d2
260         rmdir $DIR/$tdir
261         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
262 }
263 run_test 1 "mkdir; remkdir; rmdir"
264
265 test_2() {
266         test_mkdir $DIR/$tdir
267         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
268         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
269         rm -r $DIR/$tdir
270         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
271 }
272 run_test 2 "mkdir; touch; rmdir; check file"
273
274 test_3() {
275         test_mkdir $DIR/$tdir
276         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
277         touch $DIR/$tdir/$tfile
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
281 }
282 run_test 3 "mkdir; touch; rmdir; check dir"
283
284 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
285 test_4() {
286         test_mkdir -i 1 $DIR/$tdir
287
288         touch $DIR/$tdir/$tfile ||
289                 error "Create file under remote directory failed"
290
291         rmdir $DIR/$tdir &&
292                 error "Expect error removing in-use dir $DIR/$tdir"
293
294         test -d $DIR/$tdir || error "Remote directory disappeared"
295
296         rm -rf $DIR/$tdir || error "remove remote dir error"
297 }
298 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
299
300 test_5() {
301         test_mkdir $DIR/$tdir
302         test_mkdir $DIR/$tdir/d2
303         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
304         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
305         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
306 }
307 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
308
309 test_6a() {
310         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
311         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
312         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
313                 error "$tfile does not have perm 0666 or UID $UID"
314         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
315         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
316                 error "$tfile should be 0666 and owned by UID $UID"
317 }
318 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
319
320 test_6c() {
321         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
322
323         touch $DIR/$tfile
324         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
325         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $RUNAS_ID"
327         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
328         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
329                 error "$tfile should be owned by UID $RUNAS_ID"
330 }
331 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
332
333 test_6e() {
334         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
335
336         touch $DIR/$tfile
337         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
338         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by GID $UID"
340         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
341         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
342                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
343 }
344 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
345
346 test_6g() {
347         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
348
349         test_mkdir $DIR/$tdir
350         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
351         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
352         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
353         test_mkdir $DIR/$tdir/d/subdir
354         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
355                 error "$tdir/d/subdir should be GID $RUNAS_GID"
356         if [[ $MDSCOUNT -gt 1 ]]; then
357                 # check remote dir sgid inherite
358                 $LFS mkdir -i 0 $DIR/$tdir.local ||
359                         error "mkdir $tdir.local failed"
360                 chmod g+s $DIR/$tdir.local ||
361                         error "chmod $tdir.local failed"
362                 chgrp $RUNAS_GID $DIR/$tdir.local ||
363                         error "chgrp $tdir.local failed"
364                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
365                         error "mkdir $tdir.remote failed"
366                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
367                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
368                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
369                         error "$tdir.remote should be mode 02755"
370         fi
371 }
372 run_test 6g "verify new dir in sgid dir inherits group"
373
374 test_6h() { # bug 7331
375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
376
377         touch $DIR/$tfile || error "touch failed"
378         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
379         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
380                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
381         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
382                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
383 }
384 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
385
386 test_7a() {
387         test_mkdir $DIR/$tdir
388         $MCREATE $DIR/$tdir/$tfile
389         chmod 0666 $DIR/$tdir/$tfile
390         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
391                 error "$tdir/$tfile should be mode 0666"
392 }
393 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
394
395 test_7b() {
396         if [ ! -d $DIR/$tdir ]; then
397                 test_mkdir $DIR/$tdir
398         fi
399         $MCREATE $DIR/$tdir/$tfile
400         echo -n foo > $DIR/$tdir/$tfile
401         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
402         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
403 }
404 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
405
406 test_8() {
407         test_mkdir $DIR/$tdir
408         touch $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tfile mode not 0666"
412 }
413 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
414
415 test_9() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         test_mkdir $DIR/$tdir/d2/d3
419         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
420 }
421 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
422
423 test_10() {
424         test_mkdir $DIR/$tdir
425         test_mkdir $DIR/$tdir/d2
426         touch $DIR/$tdir/d2/$tfile
427         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
428                 error "$tdir/d2/$tfile not a file"
429 }
430 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
431
432 test_11() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         chmod 0666 $DIR/$tdir/d2
436         chmod 0705 $DIR/$tdir/d2
437         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
438                 error "$tdir/d2 mode not 0705"
439 }
440 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
441
442 test_12() {
443         test_mkdir $DIR/$tdir
444         touch $DIR/$tdir/$tfile
445         chmod 0666 $DIR/$tdir/$tfile
446         chmod 0654 $DIR/$tdir/$tfile
447         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
448                 error "$tdir/d2 mode not 0654"
449 }
450 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
451
452 test_13() {
453         test_mkdir $DIR/$tdir
454         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
455         >  $DIR/$tdir/$tfile
456         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
457                 error "$tdir/$tfile size not 0 after truncate"
458 }
459 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
460
461 test_14() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         rm $DIR/$tdir/$tfile
465         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
466 }
467 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
468
469 test_15() {
470         test_mkdir $DIR/$tdir
471         touch $DIR/$tdir/$tfile
472         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
473         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
474                 error "$tdir/${tfile_2} not a file after rename"
475         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
476 }
477 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
478
479 test_16() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         rm -rf $DIR/$tdir/$tfile
483         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
484 }
485 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
486
487 test_17a() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
491         ls -l $DIR/$tdir
492         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
493                 error "$tdir/l-exist not a symlink"
494         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
495                 error "$tdir/l-exist not referencing a file"
496         rm -f $DIR/$tdir/l-exist
497         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
498 }
499 run_test 17a "symlinks: create, remove (real)"
500
501 test_17b() {
502         test_mkdir $DIR/$tdir
503         ln -s no-such-file $DIR/$tdir/l-dangle
504         ls -l $DIR/$tdir
505         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
506                 error "$tdir/l-dangle not referencing no-such-file"
507         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
508                 error "$tdir/l-dangle not referencing non-existent file"
509         rm -f $DIR/$tdir/l-dangle
510         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
511 }
512 run_test 17b "symlinks: create, remove (dangling)"
513
514 test_17c() { # bug 3440 - don't save failed open RPC for replay
515         test_mkdir $DIR/$tdir
516         ln -s foo $DIR/$tdir/$tfile
517         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
518 }
519 run_test 17c "symlinks: open dangling (should return error)"
520
521 test_17d() {
522         test_mkdir $DIR/$tdir
523         ln -s foo $DIR/$tdir/$tfile
524         touch $DIR/$tdir/$tfile || error "creating to new symlink"
525 }
526 run_test 17d "symlinks: create dangling"
527
528 test_17e() {
529         test_mkdir $DIR/$tdir
530         local foo=$DIR/$tdir/$tfile
531         ln -s $foo $foo || error "create symlink failed"
532         ls -l $foo || error "ls -l failed"
533         ls $foo && error "ls not failed" || true
534 }
535 run_test 17e "symlinks: create recursive symlink (should return error)"
536
537 test_17f() {
538         test_mkdir $DIR/$tdir
539         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
541         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
543         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
544         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
545         ls -l  $DIR/$tdir
546 }
547 run_test 17f "symlinks: long and very long symlink name"
548
549 # str_repeat(S, N) generate a string that is string S repeated N times
550 str_repeat() {
551         local s=$1
552         local n=$2
553         local ret=''
554         while [ $((n -= 1)) -ge 0 ]; do
555                 ret=$ret$s
556         done
557         echo $ret
558 }
559
560 # Long symlinks and LU-2241
561 test_17g() {
562         test_mkdir $DIR/$tdir
563         local TESTS="59 60 61 4094 4095"
564
565         # Fix for inode size boundary in 2.1.4
566         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
567                 TESTS="4094 4095"
568
569         # Patch not applied to 2.2 or 2.3 branches
570         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
571         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
572                 TESTS="4094 4095"
573
574         for i in $TESTS; do
575                 local SYMNAME=$(str_repeat 'x' $i)
576                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
577                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
578         done
579 }
580 run_test 17g "symlinks: really long symlink name and inode boundaries"
581
582 test_17h() { #bug 17378
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local mdt_idx
587
588         test_mkdir $DIR/$tdir
589         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
590         $LFS setstripe -c -1 $DIR/$tdir
591         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
592         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
593         touch $DIR/$tdir/$tfile || true
594 }
595 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
596
597 test_17i() { #bug 20018
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local foo=$DIR/$tdir/$tfile
602         local mdt_idx
603
604         test_mkdir -c1 $DIR/$tdir
605         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
606         ln -s $foo $foo || error "create symlink failed"
607 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
608         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
609         ls -l $foo && error "error not detected"
610         return 0
611 }
612 run_test 17i "don't panic on short symlink (should return error)"
613
614 test_17k() { #bug 22301
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         [[ -z "$(which rsync 2>/dev/null)" ]] &&
617                 skip "no rsync command"
618         rsync --help | grep -q xattr ||
619                 skip_env "$(rsync --version | head -n1) does not support xattrs"
620         test_mkdir $DIR/$tdir
621         test_mkdir $DIR/$tdir.new
622         touch $DIR/$tdir/$tfile
623         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
624         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
625                 error "rsync failed with xattrs enabled"
626 }
627 run_test 17k "symlinks: rsync with xattrs enabled"
628
629 test_17l() { # LU-279
630         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
631                 skip "no getfattr command"
632
633         test_mkdir $DIR/$tdir
634         touch $DIR/$tdir/$tfile
635         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
636         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
637                 # -h to not follow symlinks. -m '' to list all the xattrs.
638                 # grep to remove first line: '# file: $path'.
639                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
640                 do
641                         lgetxattr_size_check $path $xattr ||
642                                 error "lgetxattr_size_check $path $xattr failed"
643                 done
644         done
645 }
646 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
647
648 # LU-1540
649 test_17m() {
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
652         remote_mds_nodsh && skip "remote MDS with nodsh"
653         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
654         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
655                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
656
657         local short_sym="0123456789"
658         local wdir=$DIR/$tdir
659         local i
660
661         test_mkdir $wdir
662         long_sym=$short_sym
663         # create a long symlink file
664         for ((i = 0; i < 4; ++i)); do
665                 long_sym=${long_sym}${long_sym}
666         done
667
668         echo "create 512 short and long symlink files under $wdir"
669         for ((i = 0; i < 256; ++i)); do
670                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
671                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
672         done
673
674         echo "erase them"
675         rm -f $wdir/*
676         sync
677         wait_delete_completed
678
679         echo "recreate the 512 symlink files with a shorter string"
680         for ((i = 0; i < 512; ++i)); do
681                 # rewrite the symlink file with a shorter string
682                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
683                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
684         done
685
686         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
687         local devname=$(mdsdevname $mds_index)
688
689         echo "stop and checking mds${mds_index}:"
690         # e2fsck should not return error
691         stop mds${mds_index}
692         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
693         rc=$?
694
695         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
696                 error "start mds${mds_index} failed"
697         df $MOUNT > /dev/null 2>&1
698         [ $rc -eq 0 ] ||
699                 error "e2fsck detected error for short/long symlink: rc=$rc"
700         rm -f $wdir/*
701 }
702 run_test 17m "run e2fsck against MDT which contains short/long symlink"
703
704 check_fs_consistency_17n() {
705         local mdt_index
706         local rc=0
707
708         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
709         # so it only check MDT1/MDT2 instead of all of MDTs.
710         for mdt_index in 1 2; do
711                 local devname=$(mdsdevname $mdt_index)
712                 # e2fsck should not return error
713                 stop mds${mdt_index}
714                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
715                         rc=$((rc + $?))
716
717                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
718                         error "mount mds$mdt_index failed"
719                 df $MOUNT > /dev/null 2>&1
720         done
721         return $rc
722 }
723
724 test_17n() {
725         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
727         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
728         remote_mds_nodsh && skip "remote MDS with nodsh"
729         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
730         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
731                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
732
733         local i
734
735         test_mkdir $DIR/$tdir
736         for ((i=0; i<10; i++)); do
737                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
738                         error "create remote dir error $i"
739                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
740                         error "create files under remote dir failed $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after create files under remote dir"
745
746         for ((i = 0; i < 10; i++)); do
747                 rm -rf $DIR/$tdir/remote_dir_${i} ||
748                         error "destroy remote dir error $i"
749         done
750
751         check_fs_consistency_17n ||
752                 error "e2fsck report error after unlink files under remote dir"
753
754         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
755                 skip "lustre < 2.4.50 does not support migrate mv"
756
757         for ((i = 0; i < 10; i++)); do
758                 mkdir -p $DIR/$tdir/remote_dir_${i}
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
762                         error "migrate remote dir error $i"
763         done
764         check_fs_consistency_17n || error "e2fsck report error after migration"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n || error "e2fsck report error after unlink"
772 }
773 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
774
775 test_17o() {
776         remote_mds_nodsh && skip "remote MDS with nodsh"
777         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
778                 skip "Need MDS version at least 2.3.64"
779
780         local wdir=$DIR/${tdir}o
781         local mdt_index
782         local rc=0
783
784         test_mkdir $wdir
785         touch $wdir/$tfile
786         mdt_index=$($LFS getstripe -m $wdir/$tfile)
787         mdt_index=$((mdt_index + 1))
788
789         cancel_lru_locks mdc
790         #fail mds will wait the failover finish then set
791         #following fail_loc to avoid interfer the recovery process.
792         fail mds${mdt_index}
793
794         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
795         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
796         ls -l $wdir/$tfile && rc=1
797         do_facet mds${mdt_index} lctl set_param fail_loc=0
798         [[ $rc -eq 0 ]] || error "stat file should fail"
799 }
800 run_test 17o "stat file with incompat LMA feature"
801
802 test_18() {
803         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
804         ls $DIR || error "Failed to ls $DIR: $?"
805 }
806 run_test 18 "touch .../f ; ls ... =============================="
807
808 test_19a() {
809         touch $DIR/$tfile
810         ls -l $DIR
811         rm $DIR/$tfile
812         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
813 }
814 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
815
816 test_19b() {
817         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
818 }
819 run_test 19b "ls -l .../f19 (should return error) =============="
820
821 test_19c() {
822         [ $RUNAS_ID -eq $UID ] &&
823                 skip_env "RUNAS_ID = UID = $UID -- skipping"
824
825         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
826 }
827 run_test 19c "$RUNAS touch .../f19 (should return error) =="
828
829 test_19d() {
830         cat $DIR/f19 && error || true
831 }
832 run_test 19d "cat .../f19 (should return error) =============="
833
834 test_20() {
835         touch $DIR/$tfile
836         rm $DIR/$tfile
837         touch $DIR/$tfile
838         rm $DIR/$tfile
839         touch $DIR/$tfile
840         rm $DIR/$tfile
841         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
842 }
843 run_test 20 "touch .../f ; ls -l ..."
844
845 test_21() {
846         test_mkdir $DIR/$tdir
847         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
848         ln -s dangle $DIR/$tdir/link
849         echo foo >> $DIR/$tdir/link
850         cat $DIR/$tdir/dangle
851         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
852         $CHECKSTAT -f -t file $DIR/$tdir/link ||
853                 error "$tdir/link not linked to a file"
854 }
855 run_test 21 "write to dangling link"
856
857 test_22() {
858         local wdir=$DIR/$tdir
859         test_mkdir $wdir
860         chown $RUNAS_ID:$RUNAS_GID $wdir
861         (cd $wdir || error "cd $wdir failed";
862                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
863                 $RUNAS tar xf -)
864         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
865         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
866         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
867                 error "checkstat -u failed"
868 }
869 run_test 22 "unpack tar archive as non-root user"
870
871 # was test_23
872 test_23a() {
873         test_mkdir $DIR/$tdir
874         local file=$DIR/$tdir/$tfile
875
876         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
877         openfile -f O_CREAT:O_EXCL $file &&
878                 error "$file recreate succeeded" || true
879 }
880 run_test 23a "O_CREAT|O_EXCL in subdir"
881
882 test_23b() { # bug 18988
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         rm -f $file
887         echo foo > $file || error "write filed"
888         echo bar >> $file || error "append filed"
889         $CHECKSTAT -s 8 $file || error "wrong size"
890         rm $file
891 }
892 run_test 23b "O_APPEND check"
893
894 # LU-9409, size with O_APPEND and tiny writes
895 test_23c() {
896         local file=$DIR/$tfile
897
898         # single dd
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
900         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
901         rm -f $file
902
903         # racing tiny writes
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
906         wait
907         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
908         rm -f $file
909
910         #racing tiny & normal writes
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
913         wait
914         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
915         rm -f $file
916
917         #racing tiny & normal writes 2, ugly numbers
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
920         wait
921         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
922         rm -f $file
923 }
924 run_test 23c "O_APPEND size checks for tiny writes"
925
926 # LU-11069 file offset is correct after appending writes
927 test_23d() {
928         local file=$DIR/$tfile
929         local offset
930
931         echo CentaurHauls > $file
932         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
933         if ((offset != 26)); then
934                 error "wrong offset, expected 26, got '$offset'"
935         fi
936 }
937 run_test 23d "file offset is correct after appending writes"
938
939 # rename sanity
940 test_24a() {
941         echo '-- same directory rename'
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.1
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
946 }
947 run_test 24a "rename file to non-existent target"
948
949 test_24b() {
950         test_mkdir $DIR/$tdir
951         touch $DIR/$tdir/$tfile.{1,2}
952         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
953         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
954         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
955 }
956 run_test 24b "rename file to existing target"
957
958 test_24c() {
959         test_mkdir $DIR/$tdir
960         test_mkdir $DIR/$tdir/d$testnum.1
961         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
962         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
963         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
964 }
965 run_test 24c "rename directory to non-existent target"
966
967 test_24d() {
968         test_mkdir -c1 $DIR/$tdir
969         test_mkdir -c1 $DIR/$tdir/d$testnum.1
970         test_mkdir -c1 $DIR/$tdir/d$testnum.2
971         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24d "rename directory to existing target"
976
977 test_24e() {
978         echo '-- cross directory renames --'
979         test_mkdir $DIR/R5a
980         test_mkdir $DIR/R5b
981         touch $DIR/R5a/f
982         mv $DIR/R5a/f $DIR/R5b/g
983         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
984         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
985 }
986 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
987
988 test_24f() {
989         test_mkdir $DIR/R6a
990         test_mkdir $DIR/R6b
991         touch $DIR/R6a/f $DIR/R6b/g
992         mv $DIR/R6a/f $DIR/R6b/g
993         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
994         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
995 }
996 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
997
998 test_24g() {
999         test_mkdir $DIR/R7a
1000         test_mkdir $DIR/R7b
1001         test_mkdir $DIR/R7a/d
1002         mv $DIR/R7a/d $DIR/R7b/e
1003         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1004         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1005 }
1006 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1007
1008 test_24h() {
1009         test_mkdir -c1 $DIR/R8a
1010         test_mkdir -c1 $DIR/R8b
1011         test_mkdir -c1 $DIR/R8a/d
1012         test_mkdir -c1 $DIR/R8b/e
1013         mrename $DIR/R8a/d $DIR/R8b/e
1014         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1015         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1016 }
1017 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1018
1019 test_24i() {
1020         echo "-- rename error cases"
1021         test_mkdir $DIR/R9
1022         test_mkdir $DIR/R9/a
1023         touch $DIR/R9/f
1024         mrename $DIR/R9/f $DIR/R9/a
1025         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1026         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1027         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1028 }
1029 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1030
1031 test_24j() {
1032         test_mkdir $DIR/R10
1033         mrename $DIR/R10/f $DIR/R10/g
1034         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1035         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1036         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1037 }
1038 run_test 24j "source does not exist ============================"
1039
1040 test_24k() {
1041         test_mkdir $DIR/R11a
1042         test_mkdir $DIR/R11a/d
1043         touch $DIR/R11a/f
1044         mv $DIR/R11a/f $DIR/R11a/d
1045         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1046         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1047 }
1048 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1049
1050 # bug 2429 - rename foo foo foo creates invalid file
1051 test_24l() {
1052         f="$DIR/f24l"
1053         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1054 }
1055 run_test 24l "Renaming a file to itself ========================"
1056
1057 test_24m() {
1058         f="$DIR/f24m"
1059         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1060         # on ext3 this does not remove either the source or target files
1061         # though the "expected" operation would be to remove the source
1062         $CHECKSTAT -t file ${f} || error "${f} missing"
1063         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1064 }
1065 run_test 24m "Renaming a file to a hard link to itself ========="
1066
1067 test_24n() {
1068     f="$DIR/f24n"
1069     # this stats the old file after it was renamed, so it should fail
1070     touch ${f}
1071     $CHECKSTAT ${f} || error "${f} missing"
1072     mv ${f} ${f}.rename
1073     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1074     $CHECKSTAT -a ${f} || error "${f} exists"
1075 }
1076 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1077
1078 test_24o() {
1079         test_mkdir $DIR/$tdir
1080         rename_many -s random -v -n 10 $DIR/$tdir
1081 }
1082 run_test 24o "rename of files during htree split"
1083
1084 test_24p() {
1085         test_mkdir $DIR/R12a
1086         test_mkdir $DIR/R12b
1087         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1088         mrename $DIR/R12a $DIR/R12b
1089         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1090         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1091         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1092         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1093 }
1094 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1095
1096 cleanup_multiop_pause() {
1097         trap 0
1098         kill -USR1 $MULTIPID
1099 }
1100
1101 test_24q() {
1102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1103
1104         test_mkdir $DIR/R13a
1105         test_mkdir $DIR/R13b
1106         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1107         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1108         MULTIPID=$!
1109
1110         trap cleanup_multiop_pause EXIT
1111         mrename $DIR/R13a $DIR/R13b
1112         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1113         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1114         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1115         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1116         cleanup_multiop_pause
1117         wait $MULTIPID || error "multiop close failed"
1118 }
1119 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1120
1121 test_24r() { #bug 3789
1122         test_mkdir $DIR/R14a
1123         test_mkdir $DIR/R14a/b
1124         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1125         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1126         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1127 }
1128 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1129
1130 test_24s() {
1131         test_mkdir $DIR/R15a
1132         test_mkdir $DIR/R15a/b
1133         test_mkdir $DIR/R15a/b/c
1134         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1136         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1137 }
1138 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1139 test_24t() {
1140         test_mkdir $DIR/R16a
1141         test_mkdir $DIR/R16a/b
1142         test_mkdir $DIR/R16a/b/c
1143         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1145         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1146 }
1147 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1148
1149 test_24u() { # bug12192
1150         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1151         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1152 }
1153 run_test 24u "create stripe file"
1154
1155 simple_cleanup_common() {
1156         local rc=0
1157         trap 0
1158         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1159
1160         local start=$SECONDS
1161         rm -rf $DIR/$tdir
1162         rc=$?
1163         wait_delete_completed
1164         echo "cleanup time $((SECONDS - start))"
1165         return $rc
1166 }
1167
1168 max_pages_per_rpc() {
1169         local mdtname="$(printf "MDT%04x" ${1:-0})"
1170         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1171 }
1172
1173 test_24v() {
1174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1175
1176         local nrfiles=${COUNT:-100000}
1177         local fname="$DIR/$tdir/$tfile"
1178
1179         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1180         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1181
1182         test_mkdir "$(dirname $fname)"
1183         # assume MDT0000 has the fewest inodes
1184         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1185         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1186         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1187
1188         trap simple_cleanup_common EXIT
1189
1190         createmany -m "$fname" $nrfiles
1191
1192         cancel_lru_locks mdc
1193         lctl set_param mdc.*.stats clear
1194
1195         # was previously test_24D: LU-6101
1196         # readdir() returns correct number of entries after cursor reload
1197         local num_ls=$(ls $DIR/$tdir | wc -l)
1198         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1199         local num_all=$(ls -a $DIR/$tdir | wc -l)
1200         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1201                 [ $num_all -ne $((nrfiles + 2)) ]; then
1202                         error "Expected $nrfiles files, got $num_ls " \
1203                                 "($num_uniq unique $num_all .&..)"
1204         fi
1205         # LU-5 large readdir
1206         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1207         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1208         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1209         # take into account of overhead in lu_dirpage header and end mark in
1210         # each page, plus one in rpc_num calculation.
1211         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1212         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1213         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1214         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1215         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1216         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1217         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1218         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1219                 error "large readdir doesn't take effect: " \
1220                       "$mds_readpage should be about $rpc_max"
1221
1222         simple_cleanup_common
1223 }
1224 run_test 24v "list large directory (test hash collision, b=17560)"
1225
1226 test_24w() { # bug21506
1227         SZ1=234852
1228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1229         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1230         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1231         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1232         [[ "$SZ1" -eq "$SZ2" ]] ||
1233                 error "Error reading at the end of the file $tfile"
1234 }
1235 run_test 24w "Reading a file larger than 4Gb"
1236
1237 test_24x() {
1238         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1240         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1241                 skip "Need MDS version at least 2.7.56"
1242
1243         local MDTIDX=1
1244         local remote_dir=$DIR/$tdir/remote_dir
1245
1246         test_mkdir $DIR/$tdir
1247         $LFS mkdir -i $MDTIDX $remote_dir ||
1248                 error "create remote directory failed"
1249
1250         test_mkdir $DIR/$tdir/src_dir
1251         touch $DIR/$tdir/src_file
1252         test_mkdir $remote_dir/tgt_dir
1253         touch $remote_dir/tgt_file
1254
1255         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1256                 error "rename dir cross MDT failed!"
1257
1258         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1259                 error "rename file cross MDT failed!"
1260
1261         touch $DIR/$tdir/ln_file
1262         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1263                 error "ln file cross MDT failed"
1264
1265         rm -rf $DIR/$tdir || error "Can not delete directories"
1266 }
1267 run_test 24x "cross MDT rename/link"
1268
1269 test_24y() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272
1273         local remote_dir=$DIR/$tdir/remote_dir
1274         local mdtidx=1
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $mdtidx $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $remote_dir/src_dir
1281         touch $remote_dir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename subdir in the same remote dir failed!"
1287
1288         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1289                 error "rename files in the same remote dir failed!"
1290
1291         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1292                 error "link files in the same remote dir failed!"
1293
1294         rm -rf $DIR/$tdir || error "Can not delete directories"
1295 }
1296 run_test 24y "rename/link on the same dir should succeed"
1297
1298 test_24z() {
1299         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1300         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1301                 skip "Need MDS version at least 2.12.51"
1302
1303         local index
1304
1305         for index in 0 1; do
1306                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1307                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1308         done
1309
1310         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1313         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1314
1315         local mdts=$(comma_list $(mdts_nodes))
1316
1317         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1318         stack_trap "do_nodes $mdts $LCTL \
1319                 set_param mdt.*.enable_remote_rename=1" EXIT
1320
1321         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1322
1323         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1324         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1325 }
1326 run_test 24z "cross-MDT rename is done as cp"
1327
1328 test_24A() { # LU-3182
1329         local NFILES=5000
1330
1331         rm -rf $DIR/$tdir
1332         test_mkdir $DIR/$tdir
1333         trap simple_cleanup_common EXIT
1334         createmany -m $DIR/$tdir/$tfile $NFILES
1335         local t=$(ls $DIR/$tdir | wc -l)
1336         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1337         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1338         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1339            [ $v -ne $((NFILES + 2)) ] ; then
1340                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1341         fi
1342
1343         simple_cleanup_common || error "Can not delete directories"
1344 }
1345 run_test 24A "readdir() returns correct number of entries."
1346
1347 test_24B() { # LU-4805
1348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1349
1350         local count
1351
1352         test_mkdir $DIR/$tdir
1353         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1354                 error "create striped dir failed"
1355
1356         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1357         [ $count -eq 2 ] || error "Expected 2, got $count"
1358
1359         touch $DIR/$tdir/striped_dir/a
1360
1361         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1362         [ $count -eq 3 ] || error "Expected 3, got $count"
1363
1364         touch $DIR/$tdir/striped_dir/.f
1365
1366         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1367         [ $count -eq 4 ] || error "Expected 4, got $count"
1368
1369         rm -rf $DIR/$tdir || error "Can not delete directories"
1370 }
1371 run_test 24B "readdir for striped dir return correct number of entries"
1372
1373 test_24C() {
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         mkdir $DIR/$tdir
1377         mkdir $DIR/$tdir/d0
1378         mkdir $DIR/$tdir/d1
1379
1380         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1381                 error "create striped dir failed"
1382
1383         cd $DIR/$tdir/d0/striped_dir
1384
1385         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1386         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1387         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d0_ino" = "$parent_ino" ] ||
1390                 error ".. wrong, expect $d0_ino, get $parent_ino"
1391
1392         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1393                 error "mv striped dir failed"
1394
1395         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d1_ino" = "$parent_ino" ] ||
1398                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1399 }
1400 run_test 24C "check .. in striped dir"
1401
1402 test_24E() {
1403         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1405
1406         mkdir -p $DIR/$tdir
1407         mkdir $DIR/$tdir/src_dir
1408         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1409                 error "create remote source failed"
1410
1411         touch $DIR/$tdir/src_dir/src_child/a
1412
1413         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1414                 error "create remote target dir failed"
1415
1416         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1417                 error "create remote target child failed"
1418
1419         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1420                 error "rename dir cross MDT failed!"
1421
1422         find $DIR/$tdir
1423
1424         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1425                 error "src_child still exists after rename"
1426
1427         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1428                 error "missing file(a) after rename"
1429
1430         rm -rf $DIR/$tdir || error "Can not delete directories"
1431 }
1432 run_test 24E "cross MDT rename/link"
1433
1434 test_24F () {
1435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1436
1437         local repeats=1000
1438         [ "$SLOW" = "no" ] && repeats=100
1439
1440         mkdir -p $DIR/$tdir
1441
1442         echo "$repeats repeats"
1443         for ((i = 0; i < repeats; i++)); do
1444                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1445                 touch $DIR/$tdir/test/a || error "touch fails"
1446                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1447                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1448         done
1449
1450         true
1451 }
1452 run_test 24F "hash order vs readdir (LU-11330)"
1453
1454 test_24G () {
1455         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1456
1457         local ino1
1458         local ino2
1459
1460         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1461         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1462         touch $DIR/$tdir-0/f1 || error "touch f1"
1463         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1464         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1465         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1466         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1467         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1468 }
1469 run_test 24G "migrate symlink in rename"
1470
1471 test_25a() {
1472         echo '== symlink sanity ============================================='
1473
1474         test_mkdir $DIR/d25
1475         ln -s d25 $DIR/s25
1476         touch $DIR/s25/foo ||
1477                 error "File creation in symlinked directory failed"
1478 }
1479 run_test 25a "create file in symlinked directory ==============="
1480
1481 test_25b() {
1482         [ ! -d $DIR/d25 ] && test_25a
1483         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1484 }
1485 run_test 25b "lookup file in symlinked directory ==============="
1486
1487 test_26a() {
1488         test_mkdir $DIR/d26
1489         test_mkdir $DIR/d26/d26-2
1490         ln -s d26/d26-2 $DIR/s26
1491         touch $DIR/s26/foo || error "File creation failed"
1492 }
1493 run_test 26a "multiple component symlink ======================="
1494
1495 test_26b() {
1496         test_mkdir -p $DIR/$tdir/d26-2
1497         ln -s $tdir/d26-2/foo $DIR/s26-2
1498         touch $DIR/s26-2 || error "File creation failed"
1499 }
1500 run_test 26b "multiple component symlink at end of lookup ======"
1501
1502 test_26c() {
1503         test_mkdir $DIR/d26.2
1504         touch $DIR/d26.2/foo
1505         ln -s d26.2 $DIR/s26.2-1
1506         ln -s s26.2-1 $DIR/s26.2-2
1507         ln -s s26.2-2 $DIR/s26.2-3
1508         chmod 0666 $DIR/s26.2-3/foo
1509 }
1510 run_test 26c "chain of symlinks"
1511
1512 # recursive symlinks (bug 439)
1513 test_26d() {
1514         ln -s d26-3/foo $DIR/d26-3
1515 }
1516 run_test 26d "create multiple component recursive symlink"
1517
1518 test_26e() {
1519         [ ! -h $DIR/d26-3 ] && test_26d
1520         rm $DIR/d26-3
1521 }
1522 run_test 26e "unlink multiple component recursive symlink"
1523
1524 # recursive symlinks (bug 7022)
1525 test_26f() {
1526         test_mkdir $DIR/$tdir
1527         test_mkdir $DIR/$tdir/$tfile
1528         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1529         test_mkdir -p lndir/bar1
1530         test_mkdir $DIR/$tdir/$tfile/$tfile
1531         cd $tfile                || error "cd $tfile failed"
1532         ln -s .. dotdot          || error "ln dotdot failed"
1533         ln -s dotdot/lndir lndir || error "ln lndir failed"
1534         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1535         output=`ls $tfile/$tfile/lndir/bar1`
1536         [ "$output" = bar1 ] && error "unexpected output"
1537         rm -r $tfile             || error "rm $tfile failed"
1538         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1539 }
1540 run_test 26f "rm -r of a directory which has recursive symlink"
1541
1542 test_27a() {
1543         test_mkdir $DIR/$tdir
1544         $LFS getstripe $DIR/$tdir
1545         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1546         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1547         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1548 }
1549 run_test 27a "one stripe file"
1550
1551 test_27b() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1553
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1556         $LFS getstripe -c $DIR/$tdir/$tfile
1557         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1558                 error "two-stripe file doesn't have two stripes"
1559
1560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1561 }
1562 run_test 27b "create and write to two stripe file"
1563
1564 # 27c family tests specific striping, setstripe -o
1565 test_27ca() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         test_mkdir -p $DIR/$tdir
1568         local osts="1"
1569
1570         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1571         $LFS getstripe -i $DIR/$tdir/$tfile
1572         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1573                 error "stripe not on specified OST"
1574
1575         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1576 }
1577 run_test 27ca "one stripe on specified OST"
1578
1579 test_27cb() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1581         test_mkdir -p $DIR/$tdir
1582         local osts="1,0"
1583         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1584         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1585         echo "$getstripe"
1586
1587         # Strip getstripe output to a space separated list of OSTs
1588         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1589                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1590         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1591                 error "stripes not on specified OSTs"
1592
1593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1594 }
1595 run_test 27cb "two stripes on specified OSTs"
1596
1597 test_27cc() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1600                 skip "server does not support overstriping"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts="0,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cc "two stripes on the same OST"
1617
1618 test_27cd() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,1,1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cd "four stripes on two OSTs"
1637
1638 test_27ce() {
1639         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1640                 skip_env "too many osts, skipping"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         # We do one more stripe than we have OSTs
1644         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1645                 skip_env "ea_inode feature disabled"
1646
1647         test_mkdir -p $DIR/$tdir
1648         local osts=""
1649         for i in $(seq 0 $OSTCOUNT);
1650         do
1651                 osts=$osts"0"
1652                 if [ $i -ne $OSTCOUNT ]; then
1653                         osts=$osts","
1654                 fi
1655         done
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27ce "more stripes than OSTs with -o"
1669
1670 test_27cf() {
1671         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1672         local pid=0
1673
1674         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1675         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1676         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1677         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1678                 error "failed to set $osp_proc=0"
1679
1680         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1681         pid=$!
1682         sleep 1
1683         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1684         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1685                 error "failed to set $osp_proc=1"
1686         wait $pid
1687         [[ $pid -ne 0 ]] ||
1688                 error "should return error due to $osp_proc=0"
1689 }
1690 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1691
1692 test_27d() {
1693         test_mkdir $DIR/$tdir
1694         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1695                 error "setstripe failed"
1696         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1698 }
1699 run_test 27d "create file with default settings"
1700
1701 test_27e() {
1702         # LU-5839 adds check for existed layout before setting it
1703         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1704                 skip "Need MDS version at least 2.7.56"
1705
1706         test_mkdir $DIR/$tdir
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1708         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1709         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1710 }
1711 run_test 27e "setstripe existing file (should return error)"
1712
1713 test_27f() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1716                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1718                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1720         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1721 }
1722 run_test 27f "setstripe with bad stripe size (should return error)"
1723
1724 test_27g() {
1725         test_mkdir $DIR/$tdir
1726         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1727         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1728                 error "$DIR/$tdir/$tfile has object"
1729 }
1730 run_test 27g "$LFS getstripe with no objects"
1731
1732 test_27ga() {
1733         test_mkdir $DIR/$tdir
1734         touch $DIR/$tdir/$tfile || error "touch failed"
1735         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1736         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1737         local rc=$?
1738         (( rc == 2 )) || error "getstripe did not return ENOENT"
1739 }
1740 run_test 27ga "$LFS getstripe with missing file (should return error)"
1741
1742 test_27i() {
1743         test_mkdir $DIR/$tdir
1744         touch $DIR/$tdir/$tfile || error "touch failed"
1745         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1746                 error "missing objects"
1747 }
1748 run_test 27i "$LFS getstripe with some objects"
1749
1750 test_27j() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1753                 error "setstripe failed" || true
1754 }
1755 run_test 27j "setstripe with bad stripe offset (should return error)"
1756
1757 test_27k() { # bug 2844
1758         test_mkdir $DIR/$tdir
1759         local file=$DIR/$tdir/$tfile
1760         local ll_max_blksize=$((4 * 1024 * 1024))
1761         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1762         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1763         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1764         dd if=/dev/zero of=$file bs=4k count=1
1765         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1766         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1767 }
1768 run_test 27k "limit i_blksize for broken user apps"
1769
1770 test_27l() {
1771         mcreate $DIR/$tfile || error "creating file"
1772         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1773                 error "setstripe should have failed" || true
1774 }
1775 run_test 27l "check setstripe permissions (should return error)"
1776
1777 test_27m() {
1778         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1779
1780         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1781                 skip_env "multiple clients -- skipping"
1782
1783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1784                    head -n1)
1785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1787         fi
1788         trap simple_cleanup_common EXIT
1789         test_mkdir $DIR/$tdir
1790         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1791         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1792                 error "dd should fill OST0"
1793         i=2
1794         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1795                 i=$((i + 1))
1796                 [ $i -gt 256 ] && break
1797         done
1798         i=$((i + 1))
1799         touch $DIR/$tdir/$tfile.$i
1800         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1801             awk '{print $1}'| grep -w "0") ] &&
1802                 error "OST0 was full but new created file still use it"
1803         i=$((i + 1))
1804         touch $DIR/$tdir/$tfile.$i
1805         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1806             awk '{print $1}'| grep -w "0") ] &&
1807                 error "OST0 was full but new created file still use it"
1808         simple_cleanup_common
1809 }
1810 run_test 27m "create file while OST0 was full"
1811
1812 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1813 # if the OST isn't full anymore.
1814 reset_enospc() {
1815         local ostidx=${1:-""}
1816         local delay
1817         local ready
1818         local get_prealloc
1819
1820         local list=$(comma_list $(osts_nodes))
1821         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1822
1823         do_nodes $list lctl set_param fail_loc=0
1824         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1825         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1826                 awk '{print $1 * 2;exit;}')
1827         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1828                         grep -v \"^0$\""
1829         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1830 }
1831
1832 __exhaust_precreations() {
1833         local OSTIDX=$1
1834         local FAILLOC=$2
1835         local FAILIDX=${3:-$OSTIDX}
1836         local ofacet=ost$((OSTIDX + 1))
1837
1838         mkdir_on_mdt0 $DIR/$tdir
1839         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1840         local mfacet=mds$((mdtidx + 1))
1841         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1842
1843         local OST=$(ostname_from_index $OSTIDX)
1844
1845         # on the mdt's osc
1846         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1847         local last_id=$(do_facet $mfacet lctl get_param -n \
1848                         osp.$mdtosc_proc1.prealloc_last_id)
1849         local next_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_next_id)
1851
1852         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1853         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1854
1855         test_mkdir -p $DIR/$tdir/${OST}
1856         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1857 #define OBD_FAIL_OST_ENOSPC              0x215
1858         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1859         echo "Creating to objid $last_id on ost $OST..."
1860         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1861         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1862         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1863 }
1864
1865 exhaust_precreations() {
1866         __exhaust_precreations $1 $2 $3
1867         sleep_maxage
1868 }
1869
1870 exhaust_all_precreations() {
1871         local i
1872         for (( i=0; i < OSTCOUNT; i++ )) ; do
1873                 __exhaust_precreations $i $1 -1
1874         done
1875         sleep_maxage
1876 }
1877
1878 test_27n() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886         exhaust_precreations 0 0x80000215
1887         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1888         touch $DIR/$tdir/$tfile || error "touch failed"
1889         $LFS getstripe $DIR/$tdir/$tfile
1890         reset_enospc
1891 }
1892 run_test 27n "create file with some full OSTs"
1893
1894 test_27o() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_all_precreations 0x215
1903
1904         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1905
1906         reset_enospc
1907         rm -rf $DIR/$tdir/*
1908 }
1909 run_test 27o "create file with all full OSTs (should error)"
1910
1911 function create_and_checktime() {
1912         local fname=$1
1913         local loops=$2
1914         local i
1915
1916         for ((i=0; i < $loops; i++)); do
1917                 local start=$SECONDS
1918                 multiop $fname-$i Oc
1919                 ((SECONDS-start < TIMEOUT)) ||
1920                         error "creation took " $((SECONDS-$start)) && return 1
1921         done
1922 }
1923
1924 test_27oo() {
1925         local mdts=$(comma_list $(mdts_nodes))
1926
1927         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1928                 skip "Need MDS version at least 2.13.57"
1929
1930         local f0=$DIR/${tfile}-0
1931         local f1=$DIR/${tfile}-1
1932
1933         wait_delete_completed
1934
1935         # refill precreated objects
1936         $LFS setstripe -i0 -c1 $f0
1937
1938         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1939         # force QoS allocation policy
1940         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1941         stack_trap "do_nodes $mdts $LCTL set_param \
1942                 lov.*.qos_threshold_rr=$saved" EXIT
1943         sleep_maxage
1944
1945         # one OST is unavailable, but still have few objects preallocated
1946         stop ost1
1947         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1948                 rm -rf $f1 $DIR/$tdir*" EXIT
1949
1950         for ((i=0; i < 7; i++)); do
1951                 mkdir $DIR/$tdir$i || error "can't create dir"
1952                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1953                         error "can't set striping"
1954         done
1955         for ((i=0; i < 7; i++)); do
1956                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1957         done
1958         wait
1959 }
1960 run_test 27oo "don't let few threads to reserve too many objects"
1961
1962 test_27p() {
1963         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966         remote_ost_nodsh && skip "remote OST with nodsh"
1967
1968         reset_enospc
1969         rm -f $DIR/$tdir/$tfile
1970         test_mkdir $DIR/$tdir
1971
1972         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1973         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1974         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1975
1976         exhaust_precreations 0 0x80000215
1977         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1978         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1979         $LFS getstripe $DIR/$tdir/$tfile
1980
1981         reset_enospc
1982 }
1983 run_test 27p "append to a truncated file with some full OSTs"
1984
1985 test_27q() {
1986         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1988         remote_mds_nodsh && skip "remote MDS with nodsh"
1989         remote_ost_nodsh && skip "remote OST with nodsh"
1990
1991         reset_enospc
1992         rm -f $DIR/$tdir/$tfile
1993
1994         mkdir_on_mdt0 $DIR/$tdir
1995         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1996         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1997                 error "truncate $DIR/$tdir/$tfile failed"
1998         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1999
2000         exhaust_all_precreations 0x215
2001
2002         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2003         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2004
2005         reset_enospc
2006 }
2007 run_test 27q "append to truncated file with all OSTs full (should error)"
2008
2009 test_27r() {
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         reset_enospc
2016         rm -f $DIR/$tdir/$tfile
2017         exhaust_precreations 0 0x80000215
2018
2019         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2020
2021         reset_enospc
2022 }
2023 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2024
2025 test_27s() { # bug 10725
2026         test_mkdir $DIR/$tdir
2027         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2028         local stripe_count=0
2029         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2030         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2031                 error "stripe width >= 2^32 succeeded" || true
2032
2033 }
2034 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2035
2036 test_27t() { # bug 10864
2037         WDIR=$(pwd)
2038         WLFS=$(which lfs)
2039         cd $DIR
2040         touch $tfile
2041         $WLFS getstripe $tfile
2042         cd $WDIR
2043 }
2044 run_test 27t "check that utils parse path correctly"
2045
2046 test_27u() { # bug 4900
2047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2048         remote_mds_nodsh && skip "remote MDS with nodsh"
2049
2050         local index
2051         local list=$(comma_list $(mdts_nodes))
2052
2053 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2054         do_nodes $list $LCTL set_param fail_loc=0x139
2055         test_mkdir -p $DIR/$tdir
2056         trap simple_cleanup_common EXIT
2057         createmany -o $DIR/$tdir/t- 1000
2058         do_nodes $list $LCTL set_param fail_loc=0
2059
2060         TLOG=$TMP/$tfile.getstripe
2061         $LFS getstripe $DIR/$tdir > $TLOG
2062         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2063         unlinkmany $DIR/$tdir/t- 1000
2064         trap 0
2065         [[ $OBJS -gt 0 ]] &&
2066                 error "$OBJS objects created on OST-0. See $TLOG" ||
2067                 rm -f $TLOG
2068 }
2069 run_test 27u "skip object creation on OSC w/o objects"
2070
2071 test_27v() { # bug 4900
2072         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074         remote_mds_nodsh && skip "remote MDS with nodsh"
2075         remote_ost_nodsh && skip "remote OST with nodsh"
2076
2077         exhaust_all_precreations 0x215
2078         reset_enospc
2079
2080         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2081
2082         touch $DIR/$tdir/$tfile
2083         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2084         # all except ost1
2085         for (( i=1; i < OSTCOUNT; i++ )); do
2086                 do_facet ost$i lctl set_param fail_loc=0x705
2087         done
2088         local START=`date +%s`
2089         createmany -o $DIR/$tdir/$tfile 32
2090
2091         local FINISH=`date +%s`
2092         local TIMEOUT=`lctl get_param -n timeout`
2093         local PROCESS=$((FINISH - START))
2094         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2095                error "$FINISH - $START >= $TIMEOUT / 2"
2096         sleep $((TIMEOUT / 2 - PROCESS))
2097         reset_enospc
2098 }
2099 run_test 27v "skip object creation on slow OST"
2100
2101 test_27w() { # bug 10997
2102         test_mkdir $DIR/$tdir
2103         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2104         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2105                 error "stripe size $size != 65536" || true
2106         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2107                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2108 }
2109 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2110
2111 test_27wa() {
2112         [[ $OSTCOUNT -lt 2 ]] &&
2113                 skip_env "skipping multiple stripe count/offset test"
2114
2115         test_mkdir $DIR/$tdir
2116         for i in $(seq 1 $OSTCOUNT); do
2117                 offset=$((i - 1))
2118                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2119                         error "setstripe -c $i -i $offset failed"
2120                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2121                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2122                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2123                 [ $index -ne $offset ] &&
2124                         error "stripe offset $index != $offset" || true
2125         done
2126 }
2127 run_test 27wa "check $LFS setstripe -c -i options"
2128
2129 test_27x() {
2130         remote_ost_nodsh && skip "remote OST with nodsh"
2131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2133
2134         OFFSET=$(($OSTCOUNT - 1))
2135         OSTIDX=0
2136         local OST=$(ostname_from_index $OSTIDX)
2137
2138         test_mkdir $DIR/$tdir
2139         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2140         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2141         sleep_maxage
2142         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2143         for i in $(seq 0 $OFFSET); do
2144                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2145                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2146                 error "OST0 was degraded but new created file still use it"
2147         done
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2149 }
2150 run_test 27x "create files while OST0 is degraded"
2151
2152 test_27y() {
2153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2154         remote_mds_nodsh && skip "remote MDS with nodsh"
2155         remote_ost_nodsh && skip "remote OST with nodsh"
2156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2157
2158         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2159         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2160                 osp.$mdtosc.prealloc_last_id)
2161         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2162                 osp.$mdtosc.prealloc_next_id)
2163         local fcount=$((last_id - next_id))
2164         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2165         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2166
2167         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2168                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2169         local OST_DEACTIVE_IDX=-1
2170         local OSC
2171         local OSTIDX
2172         local OST
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2178                         OST_DEACTIVE_IDX=$OSTIDX
2179                 fi
2180                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2181                         echo $OSC "is Deactivated:"
2182                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2183                 fi
2184         done
2185
2186         OSTIDX=$(index_from_ostuuid $OST)
2187         test_mkdir $DIR/$tdir
2188         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2189
2190         for OSC in $MDS_OSCS; do
2191                 OST=$(osc_to_ost $OSC)
2192                 OSTIDX=$(index_from_ostuuid $OST)
2193                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2194                         echo $OST "is degraded:"
2195                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2196                                                 obdfilter.$OST.degraded=1
2197                 fi
2198         done
2199
2200         sleep_maxage
2201         createmany -o $DIR/$tdir/$tfile $fcount
2202
2203         for OSC in $MDS_OSCS; do
2204                 OST=$(osc_to_ost $OSC)
2205                 OSTIDX=$(index_from_ostuuid $OST)
2206                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2207                         echo $OST "is recovered from degraded:"
2208                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2209                                                 obdfilter.$OST.degraded=0
2210                 else
2211                         do_facet $SINGLEMDS lctl --device %$OSC activate
2212                 fi
2213         done
2214
2215         # all osp devices get activated, hence -1 stripe count restored
2216         local stripe_count=0
2217
2218         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2219         # devices get activated.
2220         sleep_maxage
2221         $LFS setstripe -c -1 $DIR/$tfile
2222         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2223         rm -f $DIR/$tfile
2224         [ $stripe_count -ne $OSTCOUNT ] &&
2225                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2226         return 0
2227 }
2228 run_test 27y "create files while OST0 is degraded and the rest inactive"
2229
2230 check_seq_oid()
2231 {
2232         log "check file $1"
2233
2234         lmm_count=$($LFS getstripe -c $1)
2235         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2236         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2237
2238         local old_ifs="$IFS"
2239         IFS=$'[:]'
2240         fid=($($LFS path2fid $1))
2241         IFS="$old_ifs"
2242
2243         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2244         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2245
2246         # compare lmm_seq and lu_fid->f_seq
2247         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2248         # compare lmm_object_id and lu_fid->oid
2249         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2250
2251         # check the trusted.fid attribute of the OST objects of the file
2252         local have_obdidx=false
2253         local stripe_nr=0
2254         $LFS getstripe $1 | while read obdidx oid hex seq; do
2255                 # skip lines up to and including "obdidx"
2256                 [ -z "$obdidx" ] && break
2257                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2258                 $have_obdidx || continue
2259
2260                 local ost=$((obdidx + 1))
2261                 local dev=$(ostdevname $ost)
2262                 local oid_hex
2263
2264                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2265
2266                 seq=$(echo $seq | sed -e "s/^0x//g")
2267                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2268                         oid_hex=$(echo $oid)
2269                 else
2270                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2271                 fi
2272                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2273
2274                 local ff=""
2275                 #
2276                 # Don't unmount/remount the OSTs if we don't need to do that.
2277                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2278                 # update too, until that use mount/ll_decode_filter_fid/mount.
2279                 # Re-enable when debugfs will understand new filter_fid.
2280                 #
2281                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2282                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2283                                 $dev 2>/dev/null" | grep "parent=")
2284                 fi
2285                 if [ -z "$ff" ]; then
2286                         stop ost$ost
2287                         mount_fstype ost$ost
2288                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2289                                 $(facet_mntpt ost$ost)/$obj_file)
2290                         unmount_fstype ost$ost
2291                         start ost$ost $dev $OST_MOUNT_OPTS
2292                         clients_up
2293                 fi
2294
2295                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2296
2297                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2298
2299                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2300                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2301                 #
2302                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2303                 #       stripe_size=1048576 component_id=1 component_start=0 \
2304                 #       component_end=33554432
2305                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2306                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2307                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2308                 local ff_pstripe
2309                 if grep -q 'stripe=' <<<$ff; then
2310                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2311                 else
2312                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2313                         # into f_ver in this case.  See comment on ff_parent.
2314                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2315                 fi
2316
2317                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2318                 [ $ff_pseq = $lmm_seq ] ||
2319                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2320                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2321                 [ $ff_poid = $lmm_oid ] ||
2322                         error "FF parent OID $ff_poid != $lmm_oid"
2323                 (($ff_pstripe == $stripe_nr)) ||
2324                         error "FF stripe $ff_pstripe != $stripe_nr"
2325
2326                 stripe_nr=$((stripe_nr + 1))
2327                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2328                         continue
2329                 if grep -q 'stripe_count=' <<<$ff; then
2330                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2331                                             -e 's/ .*//' <<<$ff)
2332                         [ $lmm_count = $ff_scnt ] ||
2333                                 error "FF stripe count $lmm_count != $ff_scnt"
2334                 fi
2335         done
2336 }
2337
2338 test_27z() {
2339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2340         remote_ost_nodsh && skip "remote OST with nodsh"
2341
2342         test_mkdir $DIR/$tdir
2343         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2344                 { error "setstripe -c -1 failed"; return 1; }
2345         # We need to send a write to every object to get parent FID info set.
2346         # This _should_ also work for setattr, but does not currently.
2347         # touch $DIR/$tdir/$tfile-1 ||
2348         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2349                 { error "dd $tfile-1 failed"; return 2; }
2350         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2351                 { error "setstripe -c -1 failed"; return 3; }
2352         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2353                 { error "dd $tfile-2 failed"; return 4; }
2354
2355         # make sure write RPCs have been sent to OSTs
2356         sync; sleep 5; sync
2357
2358         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2359         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2360 }
2361 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2362
2363 test_27A() { # b=19102
2364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2365
2366         save_layout_restore_at_exit $MOUNT
2367         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2368         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2369                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2370         local default_size=$($LFS getstripe -S $MOUNT)
2371         local default_offset=$($LFS getstripe -i $MOUNT)
2372         local dsize=$(do_facet $SINGLEMDS \
2373                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2374         [ $default_size -eq $dsize ] ||
2375                 error "stripe size $default_size != $dsize"
2376         [ $default_offset -eq -1 ] ||
2377                 error "stripe offset $default_offset != -1"
2378 }
2379 run_test 27A "check filesystem-wide default LOV EA values"
2380
2381 test_27B() { # LU-2523
2382         test_mkdir $DIR/$tdir
2383         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2384         touch $DIR/$tdir/f0
2385         # open f1 with O_LOV_DELAY_CREATE
2386         # rename f0 onto f1
2387         # call setstripe ioctl on open file descriptor for f1
2388         # close
2389         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2390                 $DIR/$tdir/f0
2391
2392         rm -f $DIR/$tdir/f1
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # unlink f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2398
2399         # Allow multiop to fail in imitation of NFS's busted semantics.
2400         true
2401 }
2402 run_test 27B "call setstripe on open unlinked file/rename victim"
2403
2404 # 27C family tests full striping and overstriping
2405 test_27Ca() { #LU-2871
2406         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2407
2408         declare -a ost_idx
2409         local index
2410         local found
2411         local i
2412         local j
2413
2414         test_mkdir $DIR/$tdir
2415         cd $DIR/$tdir
2416         for i in $(seq 0 $((OSTCOUNT - 1))); do
2417                 # set stripe across all OSTs starting from OST$i
2418                 $LFS setstripe -i $i -c -1 $tfile$i
2419                 # get striping information
2420                 ost_idx=($($LFS getstripe $tfile$i |
2421                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2422                 echo ${ost_idx[@]}
2423
2424                 # check the layout
2425                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2426                         error "${#ost_idx[@]} != $OSTCOUNT"
2427
2428                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2429                         found=0
2430                         for j in $(echo ${ost_idx[@]}); do
2431                                 if [ $index -eq $j ]; then
2432                                         found=1
2433                                         break
2434                                 fi
2435                         done
2436                         [ $found = 1 ] ||
2437                                 error "Can not find $index in ${ost_idx[@]}"
2438                 done
2439         done
2440 }
2441 run_test 27Ca "check full striping across all OSTs"
2442
2443 test_27Cb() {
2444         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2445                 skip "server does not support overstriping"
2446         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2447                 skip_env "too many osts, skipping"
2448
2449         test_mkdir -p $DIR/$tdir
2450         local setcount=$(($OSTCOUNT * 2))
2451         [ $setcount -lt 160 ] || large_xattr_enabled ||
2452                 skip_env "ea_inode feature disabled"
2453
2454         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2455                 error "setstripe failed"
2456
2457         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2458         [ $count -eq $setcount ] ||
2459                 error "stripe count $count, should be $setcount"
2460
2461         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2462                 error "overstriped should be set in pattern"
2463
2464         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2465                 error "dd failed"
2466 }
2467 run_test 27Cb "more stripes than OSTs with -C"
2468
2469 test_27Cc() {
2470         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2471                 skip "server does not support overstriping"
2472         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2473
2474         test_mkdir -p $DIR/$tdir
2475         local setcount=$(($OSTCOUNT - 1))
2476
2477         [ $setcount -lt 160 ] || large_xattr_enabled ||
2478                 skip_env "ea_inode feature disabled"
2479
2480         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2481                 error "setstripe failed"
2482
2483         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2484         [ $count -eq $setcount ] ||
2485                 error "stripe count $count, should be $setcount"
2486
2487         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2488                 error "overstriped should not be set in pattern"
2489
2490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2491                 error "dd failed"
2492 }
2493 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2494
2495 test_27Cd() {
2496         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2497                 skip "server does not support overstriping"
2498         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2499         large_xattr_enabled || skip_env "ea_inode feature disabled"
2500
2501         test_mkdir -p $DIR/$tdir
2502         local setcount=$LOV_MAX_STRIPE_COUNT
2503
2504         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2505                 error "setstripe failed"
2506
2507         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2508         [ $count -eq $setcount ] ||
2509                 error "stripe count $count, should be $setcount"
2510
2511         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2512                 error "overstriped should be set in pattern"
2513
2514         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2515                 error "dd failed"
2516
2517         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2518 }
2519 run_test 27Cd "test maximum stripe count"
2520
2521 test_27Ce() {
2522         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2523                 skip "server does not support overstriping"
2524         test_mkdir -p $DIR/$tdir
2525
2526         pool_add $TESTNAME || error "Pool creation failed"
2527         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2528
2529         local setcount=8
2530
2531         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2532                 error "setstripe failed"
2533
2534         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2535         [ $count -eq $setcount ] ||
2536                 error "stripe count $count, should be $setcount"
2537
2538         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2539                 error "overstriped should be set in pattern"
2540
2541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2542                 error "dd failed"
2543
2544         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2545 }
2546 run_test 27Ce "test pool with overstriping"
2547
2548 test_27Cf() {
2549         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2550                 skip "server does not support overstriping"
2551         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip_env "too many osts, skipping"
2553
2554         test_mkdir -p $DIR/$tdir
2555
2556         local setcount=$(($OSTCOUNT * 2))
2557         [ $setcount -lt 160 ] || large_xattr_enabled ||
2558                 skip_env "ea_inode feature disabled"
2559
2560         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2561                 error "setstripe failed"
2562
2563         echo 1 > $DIR/$tdir/$tfile
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Cf "test default inheritance with overstriping"
2578
2579 test_27D() {
2580         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2581         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2582         remote_mds_nodsh && skip "remote MDS with nodsh"
2583
2584         local POOL=${POOL:-testpool}
2585         local first_ost=0
2586         local last_ost=$(($OSTCOUNT - 1))
2587         local ost_step=1
2588         local ost_list=$(seq $first_ost $ost_step $last_ost)
2589         local ost_range="$first_ost $last_ost $ost_step"
2590
2591         test_mkdir $DIR/$tdir
2592         pool_add $POOL || error "pool_add failed"
2593         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2594
2595         local skip27D
2596         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2597                 skip27D+="-s 29"
2598         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2599                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2600                         skip27D+=" -s 30,31"
2601         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2602           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2603                 skip27D+=" -s 32,33"
2604         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2605                 skip27D+=" -s 34"
2606         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2607                 error "llapi_layout_test failed"
2608
2609         destroy_test_pools || error "destroy test pools failed"
2610 }
2611 run_test 27D "validate llapi_layout API"
2612
2613 # Verify that default_easize is increased from its initial value after
2614 # accessing a widely striped file.
2615 test_27E() {
2616         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2617         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2618                 skip "client does not have LU-3338 fix"
2619
2620         # 72 bytes is the minimum space required to store striping
2621         # information for a file striped across one OST:
2622         # (sizeof(struct lov_user_md_v3) +
2623         #  sizeof(struct lov_user_ost_data_v1))
2624         local min_easize=72
2625         $LCTL set_param -n llite.*.default_easize $min_easize ||
2626                 error "lctl set_param failed"
2627         local easize=$($LCTL get_param -n llite.*.default_easize)
2628
2629         [ $easize -eq $min_easize ] ||
2630                 error "failed to set default_easize"
2631
2632         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2633                 error "setstripe failed"
2634         # In order to ensure stat() call actually talks to MDS we need to
2635         # do something drastic to this file to shake off all lock, e.g.
2636         # rename it (kills lookup lock forcing cache cleaning)
2637         mv $DIR/$tfile $DIR/${tfile}-1
2638         ls -l $DIR/${tfile}-1
2639         rm $DIR/${tfile}-1
2640
2641         easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -gt $min_easize ] ||
2644                 error "default_easize not updated"
2645 }
2646 run_test 27E "check that default extended attribute size properly increases"
2647
2648 test_27F() { # LU-5346/LU-7975
2649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2650         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2651         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2652                 skip "Need MDS version at least 2.8.51"
2653         remote_ost_nodsh && skip "remote OST with nodsh"
2654
2655         test_mkdir $DIR/$tdir
2656         rm -f $DIR/$tdir/f0
2657         $LFS setstripe -c 2 $DIR/$tdir
2658
2659         # stop all OSTs to reproduce situation for LU-7975 ticket
2660         for num in $(seq $OSTCOUNT); do
2661                 stop ost$num
2662         done
2663
2664         # open/create f0 with O_LOV_DELAY_CREATE
2665         # truncate f0 to a non-0 size
2666         # close
2667         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2668
2669         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2670         # open/write it again to force delayed layout creation
2671         cat /etc/hosts > $DIR/$tdir/f0 &
2672         catpid=$!
2673
2674         # restart OSTs
2675         for num in $(seq $OSTCOUNT); do
2676                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2677                         error "ost$num failed to start"
2678         done
2679
2680         wait $catpid || error "cat failed"
2681
2682         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2683         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2684                 error "wrong stripecount"
2685
2686 }
2687 run_test 27F "Client resend delayed layout creation with non-zero size"
2688
2689 test_27G() { #LU-10629
2690         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2691                 skip "Need MDS version at least 2.11.51"
2692         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2693         remote_mds_nodsh && skip "remote MDS with nodsh"
2694         local POOL=${POOL:-testpool}
2695         local ostrange="0 0 1"
2696
2697         test_mkdir $DIR/$tdir
2698         touch $DIR/$tdir/$tfile.nopool
2699         pool_add $POOL || error "pool_add failed"
2700         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2701         $LFS setstripe -p $POOL $DIR/$tdir
2702
2703         local pool=$($LFS getstripe -p $DIR/$tdir)
2704
2705         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2706         touch $DIR/$tdir/$tfile.default
2707         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2708         $LFS find $DIR/$tdir -type f --pool $POOL
2709         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2710         [[ "$found" == "2" ]] ||
2711                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2712
2713         $LFS setstripe -d $DIR/$tdir
2714
2715         pool=$($LFS getstripe -p -d $DIR/$tdir)
2716
2717         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2718 }
2719 run_test 27G "Clear OST pool from stripe"
2720
2721 test_27H() {
2722         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2723                 skip "Need MDS version newer than 2.11.54"
2724         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2725         test_mkdir $DIR/$tdir
2726         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2727         touch $DIR/$tdir/$tfile
2728         $LFS getstripe -c $DIR/$tdir/$tfile
2729         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2730                 error "two-stripe file doesn't have two stripes"
2731
2732         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2733         $LFS getstripe -y $DIR/$tdir/$tfile
2734         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2735              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2736                 error "expected l_ost_idx: [02]$ not matched"
2737
2738         # make sure ost list has been cleared
2739         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2740         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2741                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2742         touch $DIR/$tdir/f3
2743         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2744 }
2745 run_test 27H "Set specific OSTs stripe"
2746
2747 test_27I() {
2748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2750         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2751                 skip "Need MDS version newer than 2.12.52"
2752         local pool=$TESTNAME
2753         local ostrange="1 1 1"
2754
2755         save_layout_restore_at_exit $MOUNT
2756         $LFS setstripe -c 2 -i 0 $MOUNT
2757         pool_add $pool || error "pool_add failed"
2758         pool_add_targets $pool $ostrange ||
2759                 error "pool_add_targets failed"
2760         test_mkdir $DIR/$tdir
2761         $LFS setstripe -p $pool $DIR/$tdir
2762         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2763         $LFS getstripe $DIR/$tdir/$tfile
2764 }
2765 run_test 27I "check that root dir striping does not break parent dir one"
2766
2767 test_27J() {
2768         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2769                 skip "Need MDS version newer than 2.12.51"
2770
2771         test_mkdir $DIR/$tdir
2772         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2773         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2774
2775         # create foreign file (raw way)
2776         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2777                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2778
2779         ! $LFS setstripe --foreign --flags foo \
2780                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2781                         error "creating $tfile with '--flags foo' should fail"
2782
2783         ! $LFS setstripe --foreign --flags 0xffffffff \
2784                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2785                         error "creating $tfile w/ 0xffffffff flags should fail"
2786
2787         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2788                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2789
2790         # verify foreign file (raw way)
2791         parse_foreign_file -f $DIR/$tdir/$tfile |
2792                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2793                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2794         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2795                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2796         parse_foreign_file -f $DIR/$tdir/$tfile |
2797                 grep "lov_foreign_size: 73" ||
2798                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2799         parse_foreign_file -f $DIR/$tdir/$tfile |
2800                 grep "lov_foreign_type: 1" ||
2801                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2802         parse_foreign_file -f $DIR/$tdir/$tfile |
2803                 grep "lov_foreign_flags: 0x0000DA08" ||
2804                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2805         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2806                 grep "lov_foreign_value: 0x" |
2807                 sed -e 's/lov_foreign_value: 0x//')
2808         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2809         [[ $lov = ${lov2// /} ]] ||
2810                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2811
2812         # create foreign file (lfs + API)
2813         $LFS setstripe --foreign=none --flags 0xda08 \
2814                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2815                 error "$DIR/$tdir/${tfile}2: create failed"
2816
2817         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2818                 grep "lfm_magic:.*0x0BD70BD0" ||
2819                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2820         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2821         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2822                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2823         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2824                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2825         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2826                 grep "lfm_flags:.*0x0000DA08" ||
2827                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2828         $LFS getstripe $DIR/$tdir/${tfile}2 |
2829                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2830                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2831
2832         # modify striping should fail
2833         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2834                 error "$DIR/$tdir/$tfile: setstripe should fail"
2835         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2836                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2837
2838         # R/W should fail
2839         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2840         cat $DIR/$tdir/${tfile}2 &&
2841                 error "$DIR/$tdir/${tfile}2: read should fail"
2842         cat /etc/passwd > $DIR/$tdir/$tfile &&
2843                 error "$DIR/$tdir/$tfile: write should fail"
2844         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2845                 error "$DIR/$tdir/${tfile}2: write should fail"
2846
2847         # chmod should work
2848         chmod 222 $DIR/$tdir/$tfile ||
2849                 error "$DIR/$tdir/$tfile: chmod failed"
2850         chmod 222 $DIR/$tdir/${tfile}2 ||
2851                 error "$DIR/$tdir/${tfile}2: chmod failed"
2852
2853         # chown should work
2854         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2855                 error "$DIR/$tdir/$tfile: chown failed"
2856         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2857                 error "$DIR/$tdir/${tfile}2: chown failed"
2858
2859         # rename should work
2860         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2861                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2862         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2863                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2864
2865         #remove foreign file
2866         rm $DIR/$tdir/${tfile}.new ||
2867                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2868         rm $DIR/$tdir/${tfile}2.new ||
2869                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2870 }
2871 run_test 27J "basic ops on file with foreign LOV"
2872
2873 test_27K() {
2874         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2875                 skip "Need MDS version newer than 2.12.49"
2876
2877         test_mkdir $DIR/$tdir
2878         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2879         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2880
2881         # create foreign dir (raw way)
2882         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2883                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2884
2885         ! $LFS setdirstripe --foreign --flags foo \
2886                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2887                         error "creating $tdir with '--flags foo' should fail"
2888
2889         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2890                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2891                         error "creating $tdir w/ 0xffffffff flags should fail"
2892
2893         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2894                 error "create_foreign_dir FAILED"
2895
2896         # verify foreign dir (raw way)
2897         parse_foreign_dir -d $DIR/$tdir/$tdir |
2898                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2899                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2900         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2901                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2902         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2903                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2904         parse_foreign_dir -d $DIR/$tdir/$tdir |
2905                 grep "lmv_foreign_flags: 55813$" ||
2906                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2907         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2908                 grep "lmv_foreign_value: 0x" |
2909                 sed 's/lmv_foreign_value: 0x//')
2910         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2911                 sed 's/ //g')
2912         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2913
2914         # create foreign dir (lfs + API)
2915         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2916                 $DIR/$tdir/${tdir}2 ||
2917                 error "$DIR/$tdir/${tdir}2: create failed"
2918
2919         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2920                 grep "lfm_magic:.*0x0CD50CD0" ||
2921                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2922         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2923         # - sizeof(lfm_type) - sizeof(lfm_flags)
2924         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2925                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2926         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2927                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2928         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2929                 grep "lfm_flags:.*0x0000DA05" ||
2930                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2931         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2932                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2933                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2934
2935         # file create in dir should fail
2936         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2937         touch $DIR/$tdir/${tdir}2/$tfile &&
2938                 "$DIR/${tdir}2: file create should fail"
2939
2940         # chmod should work
2941         chmod 777 $DIR/$tdir/$tdir ||
2942                 error "$DIR/$tdir: chmod failed"
2943         chmod 777 $DIR/$tdir/${tdir}2 ||
2944                 error "$DIR/${tdir}2: chmod failed"
2945
2946         # chown should work
2947         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2948                 error "$DIR/$tdir: chown failed"
2949         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2950                 error "$DIR/${tdir}2: chown failed"
2951
2952         # rename should work
2953         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2954                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2955         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2956                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2957
2958         #remove foreign dir
2959         rmdir $DIR/$tdir/${tdir}.new ||
2960                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2961         rmdir $DIR/$tdir/${tdir}2.new ||
2962                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2963 }
2964 run_test 27K "basic ops on dir with foreign LMV"
2965
2966 test_27L() {
2967         remote_mds_nodsh && skip "remote MDS with nodsh"
2968
2969         local POOL=${POOL:-$TESTNAME}
2970
2971         pool_add $POOL || error "pool_add failed"
2972
2973         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2974                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2975                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2976 }
2977 run_test 27L "lfs pool_list gives correct pool name"
2978
2979 test_27M() {
2980         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2981                 skip "Need MDS version >= than 2.12.57"
2982         remote_mds_nodsh && skip "remote MDS with nodsh"
2983         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2984
2985         test_mkdir $DIR/$tdir
2986
2987         # Set default striping on directory
2988         $LFS setstripe -C 4 $DIR/$tdir
2989
2990         echo 1 > $DIR/$tdir/${tfile}.1
2991         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2992         local setcount=4
2993         [ $count -eq $setcount ] ||
2994                 error "(1) stripe count $count, should be $setcount"
2995
2996         # Capture existing append_stripe_count setting for restore
2997         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2998         local mdts=$(comma_list $(mdts_nodes))
2999         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3000
3001         local appendcount=$orig_count
3002         echo 1 >> $DIR/$tdir/${tfile}.2_append
3003         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3004         [ $count -eq $appendcount ] ||
3005                 error "(2)stripe count $count, should be $appendcount for append"
3006
3007         # Disable O_APPEND striping, verify it works
3008         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3009
3010         # Should now get the default striping, which is 4
3011         setcount=4
3012         echo 1 >> $DIR/$tdir/${tfile}.3_append
3013         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3014         [ $count -eq $setcount ] ||
3015                 error "(3) stripe count $count, should be $setcount"
3016
3017         # Try changing the stripe count for append files
3018         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3019
3020         # Append striping is now 2 (directory default is still 4)
3021         appendcount=2
3022         echo 1 >> $DIR/$tdir/${tfile}.4_append
3023         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3024         [ $count -eq $appendcount ] ||
3025                 error "(4) stripe count $count, should be $appendcount for append"
3026
3027         # Test append stripe count of -1
3028         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3029         appendcount=$OSTCOUNT
3030         echo 1 >> $DIR/$tdir/${tfile}.5
3031         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3032         [ $count -eq $appendcount ] ||
3033                 error "(5) stripe count $count, should be $appendcount for append"
3034
3035         # Set append striping back to default of 1
3036         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3037
3038         # Try a new default striping, PFL + DOM
3039         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3040
3041         # Create normal DOM file, DOM returns stripe count == 0
3042         setcount=0
3043         touch $DIR/$tdir/${tfile}.6
3044         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3045         [ $count -eq $setcount ] ||
3046                 error "(6) stripe count $count, should be $setcount"
3047
3048         # Show
3049         appendcount=1
3050         echo 1 >> $DIR/$tdir/${tfile}.7_append
3051         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3052         [ $count -eq $appendcount ] ||
3053                 error "(7) stripe count $count, should be $appendcount for append"
3054
3055         # Clean up DOM layout
3056         $LFS setstripe -d $DIR/$tdir
3057
3058         # Now test that append striping works when layout is from root
3059         $LFS setstripe -c 2 $MOUNT
3060         # Make a special directory for this
3061         mkdir $DIR/${tdir}/${tdir}.2
3062         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3063
3064         # Verify for normal file
3065         setcount=2
3066         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3067         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3068         [ $count -eq $setcount ] ||
3069                 error "(8) stripe count $count, should be $setcount"
3070
3071         appendcount=1
3072         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3073         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3074         [ $count -eq $appendcount ] ||
3075                 error "(9) stripe count $count, should be $appendcount for append"
3076
3077         # Now test O_APPEND striping with pools
3078         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3079         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3080
3081         # Create the pool
3082         pool_add $TESTNAME || error "pool creation failed"
3083         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3084
3085         echo 1 >> $DIR/$tdir/${tfile}.10_append
3086
3087         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3088         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3089
3090         # Check that count is still correct
3091         appendcount=1
3092         echo 1 >> $DIR/$tdir/${tfile}.11_append
3093         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3094         [ $count -eq $appendcount ] ||
3095                 error "(11) stripe count $count, should be $appendcount for append"
3096
3097         # Disable O_APPEND stripe count, verify pool works separately
3098         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3099
3100         echo 1 >> $DIR/$tdir/${tfile}.12_append
3101
3102         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3103         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3104
3105         # Remove pool setting, verify it's not applied
3106         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3107
3108         echo 1 >> $DIR/$tdir/${tfile}.13_append
3109
3110         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3111         [ "$pool" = "" ] || error "(13) pool found: $pool"
3112 }
3113 run_test 27M "test O_APPEND striping"
3114
3115 test_27N() {
3116         combined_mgs_mds && skip "needs separate MGS/MDT"
3117
3118         pool_add $TESTNAME || error "pool_add failed"
3119         do_facet mgs "$LCTL pool_list $FSNAME" |
3120                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3121                 error "lctl pool_list on MGS failed"
3122 }
3123 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3124
3125 clean_foreign_symlink() {
3126         trap 0
3127         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3128         for i in $DIR/$tdir/* ; do
3129                 $LFS unlink_foreign $i || true
3130         done
3131 }
3132
3133 test_27O() {
3134         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3135                 skip "Need MDS version newer than 2.12.51"
3136
3137         test_mkdir $DIR/$tdir
3138         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3139         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3140
3141         trap clean_foreign_symlink EXIT
3142
3143         # enable foreign_symlink behaviour
3144         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3145
3146         # foreign symlink LOV format is a partial path by default
3147
3148         # create foreign file (lfs + API)
3149         $LFS setstripe --foreign=symlink --flags 0xda05 \
3150                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3151                 error "$DIR/$tdir/${tfile}: create failed"
3152
3153         $LFS getstripe -v $DIR/$tdir/${tfile} |
3154                 grep "lfm_magic:.*0x0BD70BD0" ||
3155                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3156         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3158         $LFS getstripe -v $DIR/$tdir/${tfile} |
3159                 grep "lfm_flags:.*0x0000DA05" ||
3160                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3161         $LFS getstripe $DIR/$tdir/${tfile} |
3162                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3163                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3164
3165         # modify striping should fail
3166         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3167                 error "$DIR/$tdir/$tfile: setstripe should fail"
3168
3169         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3170         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3171         cat /etc/passwd > $DIR/$tdir/$tfile &&
3172                 error "$DIR/$tdir/$tfile: write should fail"
3173
3174         # rename should succeed
3175         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3176                 error "$DIR/$tdir/$tfile: rename has failed"
3177
3178         #remove foreign_symlink file should fail
3179         rm $DIR/$tdir/${tfile}.new &&
3180                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3181
3182         #test fake symlink
3183         mkdir /tmp/${uuid1} ||
3184                 error "/tmp/${uuid1}: mkdir has failed"
3185         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3186                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3187         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3188         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3189                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3190         #read should succeed now
3191         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3192                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3193         #write should succeed now
3194         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3195                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3196         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3197                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3198         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3199                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3200
3201         #check that getstripe still works
3202         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3203                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3204
3205         # chmod should still succeed
3206         chmod 644 $DIR/$tdir/${tfile}.new ||
3207                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3208
3209         # chown should still succeed
3210         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3211                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3212
3213         # rename should still succeed
3214         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3215                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3216
3217         #remove foreign_symlink file should still fail
3218         rm $DIR/$tdir/${tfile} &&
3219                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3220
3221         #use special ioctl() to unlink foreign_symlink file
3222         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3223                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3224
3225 }
3226 run_test 27O "basic ops on foreign file of symlink type"
3227
3228 test_27P() {
3229         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3230                 skip "Need MDS version newer than 2.12.49"
3231
3232         test_mkdir $DIR/$tdir
3233         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3234         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3235
3236         trap clean_foreign_symlink EXIT
3237
3238         # enable foreign_symlink behaviour
3239         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3240
3241         # foreign symlink LMV format is a partial path by default
3242
3243         # create foreign dir (lfs + API)
3244         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3245                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3246                 error "$DIR/$tdir/${tdir}: create failed"
3247
3248         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3249                 grep "lfm_magic:.*0x0CD50CD0" ||
3250                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3251         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3252                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3253         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3254                 grep "lfm_flags:.*0x0000DA05" ||
3255                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3256         $LFS getdirstripe $DIR/$tdir/${tdir} |
3257                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3258                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3259
3260         # file create in dir should fail
3261         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3262         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3263
3264         # rename should succeed
3265         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3266                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3267
3268         #remove foreign_symlink dir should fail
3269         rmdir $DIR/$tdir/${tdir}.new &&
3270                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3271
3272         #test fake symlink
3273         mkdir -p /tmp/${uuid1}/${uuid2} ||
3274                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3275         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3276                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3277         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3278         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3279                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3280         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3281                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3282
3283         #check that getstripe fails now that foreign_symlink enabled
3284         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3285                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3286
3287         # file create in dir should work now
3288         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3289                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3290         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3291                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3292         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3293                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3294
3295         # chmod should still succeed
3296         chmod 755 $DIR/$tdir/${tdir}.new ||
3297                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3298
3299         # chown should still succeed
3300         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3301                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3302
3303         # rename should still succeed
3304         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3305                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3306
3307         #remove foreign_symlink dir should still fail
3308         rmdir $DIR/$tdir/${tdir} &&
3309                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3310
3311         #use special ioctl() to unlink foreign_symlink file
3312         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3313                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3314
3315         #created file should still exist
3316         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3317                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3318         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3319                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3320 }
3321 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3322
3323 test_27Q() {
3324         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3325         stack_trap "rm -f $TMP/$tfile*"
3326
3327         test_mkdir $DIR/$tdir-1
3328         test_mkdir $DIR/$tdir-2
3329
3330         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3331         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3332
3333         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3334         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3335
3336         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3337         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3338
3339         # Create some bad symlinks and ensure that we don't loop
3340         # forever or something. These should return ELOOP (40) and
3341         # ENOENT (2) but I don't want to test for that because there's
3342         # always some weirdo architecture that needs to ruin
3343         # everything by defining these error numbers differently.
3344
3345         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3346         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3347
3348         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3349         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3350
3351         return 0
3352 }
3353 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3354
3355 # createtest also checks that device nodes are created and
3356 # then visible correctly (#2091)
3357 test_28() { # bug 2091
3358         test_mkdir $DIR/d28
3359         $CREATETEST $DIR/d28/ct || error "createtest failed"
3360 }
3361 run_test 28 "create/mknod/mkdir with bad file types ============"
3362
3363 test_29() {
3364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3365
3366         sync; sleep 1; sync # flush out any dirty pages from previous tests
3367         cancel_lru_locks
3368         test_mkdir $DIR/d29
3369         touch $DIR/d29/foo
3370         log 'first d29'
3371         ls -l $DIR/d29
3372
3373         declare -i LOCKCOUNTORIG=0
3374         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3375                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3376         done
3377         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3378
3379         declare -i LOCKUNUSEDCOUNTORIG=0
3380         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3381                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3382         done
3383
3384         log 'second d29'
3385         ls -l $DIR/d29
3386         log 'done'
3387
3388         declare -i LOCKCOUNTCURRENT=0
3389         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3390                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3391         done
3392
3393         declare -i LOCKUNUSEDCOUNTCURRENT=0
3394         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3395                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3396         done
3397
3398         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3399                 $LCTL set_param -n ldlm.dump_namespaces ""
3400                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3401                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3402                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3403                 return 2
3404         fi
3405         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3406                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3407                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3408                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3409                 return 3
3410         fi
3411 }
3412 run_test 29 "IT_GETATTR regression  ============================"
3413
3414 test_30a() { # was test_30
3415         cp $(which ls) $DIR || cp /bin/ls $DIR
3416         $DIR/ls / || error "Can't execute binary from lustre"
3417         rm $DIR/ls
3418 }
3419 run_test 30a "execute binary from Lustre (execve) =============="
3420
3421 test_30b() {
3422         cp `which ls` $DIR || cp /bin/ls $DIR
3423         chmod go+rx $DIR/ls
3424         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3425         rm $DIR/ls
3426 }
3427 run_test 30b "execute binary from Lustre as non-root ==========="
3428
3429 test_30c() { # b=22376
3430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3431
3432         cp $(which ls) $DIR || cp /bin/ls $DIR
3433         chmod a-rw $DIR/ls
3434         cancel_lru_locks mdc
3435         cancel_lru_locks osc
3436         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3437         rm -f $DIR/ls
3438 }
3439 run_test 30c "execute binary from Lustre without read perms ===="
3440
3441 test_30d() {
3442         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3443
3444         for i in {1..10}; do
3445                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3446                 local PID=$!
3447                 sleep 1
3448                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3449                 wait $PID || error "executing dd from Lustre failed"
3450                 rm -f $DIR/$tfile
3451         done
3452
3453         rm -f $DIR/dd
3454 }
3455 run_test 30d "execute binary from Lustre while clear locks"
3456
3457 test_31a() {
3458         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3459         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3460 }
3461 run_test 31a "open-unlink file =================================="
3462
3463 test_31b() {
3464         touch $DIR/f31 || error "touch $DIR/f31 failed"
3465         ln $DIR/f31 $DIR/f31b || error "ln failed"
3466         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3467         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3468 }
3469 run_test 31b "unlink file with multiple links while open ======="
3470
3471 test_31c() {
3472         touch $DIR/f31 || error "touch $DIR/f31 failed"
3473         ln $DIR/f31 $DIR/f31c || error "ln failed"
3474         multiop_bg_pause $DIR/f31 O_uc ||
3475                 error "multiop_bg_pause for $DIR/f31 failed"
3476         MULTIPID=$!
3477         $MULTIOP $DIR/f31c Ouc
3478         kill -USR1 $MULTIPID
3479         wait $MULTIPID
3480 }
3481 run_test 31c "open-unlink file with multiple links ============="
3482
3483 test_31d() {
3484         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3485         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3486 }
3487 run_test 31d "remove of open directory ========================="
3488
3489 test_31e() { # bug 2904
3490         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3491 }
3492 run_test 31e "remove of open non-empty directory ==============="
3493
3494 test_31f() { # bug 4554
3495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3496
3497         set -vx
3498         test_mkdir $DIR/d31f
3499         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3500         cp /etc/hosts $DIR/d31f
3501         ls -l $DIR/d31f
3502         $LFS getstripe $DIR/d31f/hosts
3503         multiop_bg_pause $DIR/d31f D_c || return 1
3504         MULTIPID=$!
3505
3506         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3507         test_mkdir $DIR/d31f
3508         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3509         cp /etc/hosts $DIR/d31f
3510         ls -l $DIR/d31f
3511         $LFS getstripe $DIR/d31f/hosts
3512         multiop_bg_pause $DIR/d31f D_c || return 1
3513         MULTIPID2=$!
3514
3515         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3516         wait $MULTIPID || error "first opendir $MULTIPID failed"
3517
3518         sleep 6
3519
3520         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3521         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3522         set +vx
3523 }
3524 run_test 31f "remove of open directory with open-unlink file ==="
3525
3526 test_31g() {
3527         echo "-- cross directory link --"
3528         test_mkdir -c1 $DIR/${tdir}ga
3529         test_mkdir -c1 $DIR/${tdir}gb
3530         touch $DIR/${tdir}ga/f
3531         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3532         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3533         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3534         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3535         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3536 }
3537 run_test 31g "cross directory link==============="
3538
3539 test_31h() {
3540         echo "-- cross directory link --"
3541         test_mkdir -c1 $DIR/${tdir}
3542         test_mkdir -c1 $DIR/${tdir}/dir
3543         touch $DIR/${tdir}/f
3544         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3545         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3546         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3547         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3548         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3549 }
3550 run_test 31h "cross directory link under child==============="
3551
3552 test_31i() {
3553         echo "-- cross directory link --"
3554         test_mkdir -c1 $DIR/$tdir
3555         test_mkdir -c1 $DIR/$tdir/dir
3556         touch $DIR/$tdir/dir/f
3557         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3558         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3559         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3560         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3561         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3562 }
3563 run_test 31i "cross directory link under parent==============="
3564
3565 test_31j() {
3566         test_mkdir -c1 -p $DIR/$tdir
3567         test_mkdir -c1 -p $DIR/$tdir/dir1
3568         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3569         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3570         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3571         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3572         return 0
3573 }
3574 run_test 31j "link for directory==============="
3575
3576 test_31k() {
3577         test_mkdir -c1 -p $DIR/$tdir
3578         touch $DIR/$tdir/s
3579         touch $DIR/$tdir/exist
3580         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3581         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3582         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3583         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3584         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3585         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3586         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3587         return 0
3588 }
3589 run_test 31k "link to file: the same, non-existing, dir==============="
3590
3591 test_31m() {
3592         mkdir $DIR/d31m
3593         touch $DIR/d31m/s
3594         mkdir $DIR/d31m2
3595         touch $DIR/d31m2/exist
3596         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3597         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3598         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3599         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3600         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3601         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3602         return 0
3603 }
3604 run_test 31m "link to file: the same, non-existing, dir==============="
3605
3606 test_31n() {
3607         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3608         nlink=$(stat --format=%h $DIR/$tfile)
3609         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3610         local fd=$(free_fd)
3611         local cmd="exec $fd<$DIR/$tfile"
3612         eval $cmd
3613         cmd="exec $fd<&-"
3614         trap "eval $cmd" EXIT
3615         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3616         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3617         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3618         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3619         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3620         eval $cmd
3621 }
3622 run_test 31n "check link count of unlinked file"
3623
3624 link_one() {
3625         local tempfile=$(mktemp $1_XXXXXX)
3626         mlink $tempfile $1 2> /dev/null &&
3627                 echo "$BASHPID: link $tempfile to $1 succeeded"
3628         munlink $tempfile
3629 }
3630
3631 test_31o() { # LU-2901
3632         test_mkdir $DIR/$tdir
3633         for LOOP in $(seq 100); do
3634                 rm -f $DIR/$tdir/$tfile*
3635                 for THREAD in $(seq 8); do
3636                         link_one $DIR/$tdir/$tfile.$LOOP &
3637                 done
3638                 wait
3639                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3640                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3641                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3642                         break || true
3643         done
3644 }
3645 run_test 31o "duplicate hard links with same filename"
3646
3647 test_31p() {
3648         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3649
3650         test_mkdir $DIR/$tdir
3651         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3652         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3653
3654         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3655                 error "open unlink test1 failed"
3656         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3657                 error "open unlink test2 failed"
3658
3659         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3660                 error "test1 still exists"
3661         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3662                 error "test2 still exists"
3663 }
3664 run_test 31p "remove of open striped directory"
3665
3666 test_31q() {
3667         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3668
3669         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3670         index=$($LFS getdirstripe -i $DIR/$tdir)
3671         [ $index -eq 3 ] || error "first stripe index $index != 3"
3672         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3673         [ $index -eq 1 ] || error "second stripe index $index != 1"
3674
3675         # when "-c <stripe_count>" is set, the number of MDTs specified after
3676         # "-i" should equal to the stripe count
3677         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3678 }
3679 run_test 31q "create striped directory on specific MDTs"
3680
3681 cleanup_test32_mount() {
3682         local rc=0
3683         trap 0
3684         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3685         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3686         losetup -d $loopdev || true
3687         rm -rf $DIR/$tdir
3688         return $rc
3689 }
3690
3691 test_32a() {
3692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3693
3694         echo "== more mountpoints and symlinks ================="
3695         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3696         trap cleanup_test32_mount EXIT
3697         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3698         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3699                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3700         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3701                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3702         cleanup_test32_mount
3703 }
3704 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3705
3706 test_32b() {
3707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3708
3709         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3710         trap cleanup_test32_mount EXIT
3711         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3712         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3713                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3714         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3715                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3716         cleanup_test32_mount
3717 }
3718 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3719
3720 test_32c() {
3721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3722
3723         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3724         trap cleanup_test32_mount EXIT
3725         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3726         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3727                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3728         test_mkdir -p $DIR/$tdir/d2/test_dir
3729         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3730                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3731         cleanup_test32_mount
3732 }
3733 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3734
3735 test_32d() {
3736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3737
3738         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3739         trap cleanup_test32_mount EXIT
3740         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3741         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3742                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3743         test_mkdir -p $DIR/$tdir/d2/test_dir
3744         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3745                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3746         cleanup_test32_mount
3747 }
3748 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3749
3750 test_32e() {
3751         rm -fr $DIR/$tdir
3752         test_mkdir -p $DIR/$tdir/tmp
3753         local tmp_dir=$DIR/$tdir/tmp
3754         ln -s $DIR/$tdir $tmp_dir/symlink11
3755         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3756         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3757         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3758 }
3759 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3760
3761 test_32f() {
3762         rm -fr $DIR/$tdir
3763         test_mkdir -p $DIR/$tdir/tmp
3764         local tmp_dir=$DIR/$tdir/tmp
3765         ln -s $DIR/$tdir $tmp_dir/symlink11
3766         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3767         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3768         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3769 }
3770 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3771
3772 test_32g() {
3773         local tmp_dir=$DIR/$tdir/tmp
3774         test_mkdir -p $tmp_dir
3775         test_mkdir $DIR/${tdir}2
3776         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3777         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3778         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3779         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3780         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3781         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3782 }
3783 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3784
3785 test_32h() {
3786         rm -fr $DIR/$tdir $DIR/${tdir}2
3787         tmp_dir=$DIR/$tdir/tmp
3788         test_mkdir -p $tmp_dir
3789         test_mkdir $DIR/${tdir}2
3790         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3791         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3792         ls $tmp_dir/symlink12 || error "listing symlink12"
3793         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3794 }
3795 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3796
3797 test_32i() {
3798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3799
3800         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3801         trap cleanup_test32_mount EXIT
3802         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3803         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3804                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3805         touch $DIR/$tdir/test_file
3806         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3807                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3808         cleanup_test32_mount
3809 }
3810 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3811
3812 test_32j() {
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814
3815         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3816         trap cleanup_test32_mount EXIT
3817         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3818         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3819                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3820         touch $DIR/$tdir/test_file
3821         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3822                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3823         cleanup_test32_mount
3824 }
3825 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3826
3827 test_32k() {
3828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3829
3830         rm -fr $DIR/$tdir
3831         trap cleanup_test32_mount EXIT
3832         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3833         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3834                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3835         test_mkdir -p $DIR/$tdir/d2
3836         touch $DIR/$tdir/d2/test_file || error "touch failed"
3837         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3838                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3839         cleanup_test32_mount
3840 }
3841 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3842
3843 test_32l() {
3844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3845
3846         rm -fr $DIR/$tdir
3847         trap cleanup_test32_mount EXIT
3848         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3849         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3850                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3851         test_mkdir -p $DIR/$tdir/d2
3852         touch $DIR/$tdir/d2/test_file || error "touch failed"
3853         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3854                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3855         cleanup_test32_mount
3856 }
3857 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3858
3859 test_32m() {
3860         rm -fr $DIR/d32m
3861         test_mkdir -p $DIR/d32m/tmp
3862         TMP_DIR=$DIR/d32m/tmp
3863         ln -s $DIR $TMP_DIR/symlink11
3864         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3865         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3866                 error "symlink11 not a link"
3867         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3868                 error "symlink01 not a link"
3869 }
3870 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3871
3872 test_32n() {
3873         rm -fr $DIR/d32n
3874         test_mkdir -p $DIR/d32n/tmp
3875         TMP_DIR=$DIR/d32n/tmp
3876         ln -s $DIR $TMP_DIR/symlink11
3877         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3878         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3879         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3880 }
3881 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3882
3883 test_32o() {
3884         touch $DIR/$tfile
3885         test_mkdir -p $DIR/d32o/tmp
3886         TMP_DIR=$DIR/d32o/tmp
3887         ln -s $DIR/$tfile $TMP_DIR/symlink12
3888         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3889         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3890                 error "symlink12 not a link"
3891         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3892         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3893                 error "$DIR/d32o/tmp/symlink12 not file type"
3894         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3895                 error "$DIR/d32o/symlink02 not file type"
3896 }
3897 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3898
3899 test_32p() {
3900         log 32p_1
3901         rm -fr $DIR/d32p
3902         log 32p_2
3903         rm -f $DIR/$tfile
3904         log 32p_3
3905         touch $DIR/$tfile
3906         log 32p_4
3907         test_mkdir -p $DIR/d32p/tmp
3908         log 32p_5
3909         TMP_DIR=$DIR/d32p/tmp
3910         log 32p_6
3911         ln -s $DIR/$tfile $TMP_DIR/symlink12
3912         log 32p_7
3913         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3914         log 32p_8
3915         cat $DIR/d32p/tmp/symlink12 ||
3916                 error "Can't open $DIR/d32p/tmp/symlink12"
3917         log 32p_9
3918         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3919         log 32p_10
3920 }
3921 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3922
3923 test_32q() {
3924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3925
3926         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3927         trap cleanup_test32_mount EXIT
3928         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3929         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3933         cleanup_test32_mount
3934 }
3935 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3936
3937 test_32r() {
3938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3939
3940         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3941         trap cleanup_test32_mount EXIT
3942         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3943         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3944         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3945                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3946         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3947         cleanup_test32_mount
3948 }
3949 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3950
3951 test_33aa() {
3952         rm -f $DIR/$tfile
3953         touch $DIR/$tfile
3954         chmod 444 $DIR/$tfile
3955         chown $RUNAS_ID $DIR/$tfile
3956         log 33_1
3957         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3958         log 33_2
3959 }
3960 run_test 33aa "write file with mode 444 (should return error)"
3961
3962 test_33a() {
3963         rm -fr $DIR/$tdir
3964         test_mkdir $DIR/$tdir
3965         chown $RUNAS_ID $DIR/$tdir
3966         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3967                 error "$RUNAS create $tdir/$tfile failed"
3968         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3969                 error "open RDWR" || true
3970 }
3971 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3972
3973 test_33b() {
3974         rm -fr $DIR/$tdir
3975         test_mkdir $DIR/$tdir
3976         chown $RUNAS_ID $DIR/$tdir
3977         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3978 }
3979 run_test 33b "test open file with malformed flags (No panic)"
3980
3981 test_33c() {
3982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3983         remote_ost_nodsh && skip "remote OST with nodsh"
3984
3985         local ostnum
3986         local ostname
3987         local write_bytes
3988         local all_zeros
3989
3990         all_zeros=true
3991         test_mkdir $DIR/$tdir
3992         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3993
3994         sync
3995         for ostnum in $(seq $OSTCOUNT); do
3996                 # test-framework's OST numbering is one-based, while Lustre's
3997                 # is zero-based
3998                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3999                 # check if at least some write_bytes stats are counted
4000                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4001                               obdfilter.$ostname.stats |
4002                               awk '/^write_bytes/ {print $7}' )
4003                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4004                 if (( ${write_bytes:-0} > 0 )); then
4005                         all_zeros=false
4006                         break
4007                 fi
4008         done
4009
4010         $all_zeros || return 0
4011
4012         # Write four bytes
4013         echo foo > $DIR/$tdir/bar
4014         # Really write them
4015         sync
4016
4017         # Total up write_bytes after writing.  We'd better find non-zeros.
4018         for ostnum in $(seq $OSTCOUNT); do
4019                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4020                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4021                               obdfilter/$ostname/stats |
4022                               awk '/^write_bytes/ {print $7}' )
4023                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4024                 if (( ${write_bytes:-0} > 0 )); then
4025                         all_zeros=false
4026                         break
4027                 fi
4028         done
4029
4030         if $all_zeros; then
4031                 for ostnum in $(seq $OSTCOUNT); do
4032                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4033                         echo "Check write_bytes is in obdfilter.*.stats:"
4034                         do_facet ost$ostnum lctl get_param -n \
4035                                 obdfilter.$ostname.stats
4036                 done
4037                 error "OST not keeping write_bytes stats (b=22312)"
4038         fi
4039 }
4040 run_test 33c "test write_bytes stats"
4041
4042 test_33d() {
4043         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4045
4046         local MDTIDX=1
4047         local remote_dir=$DIR/$tdir/remote_dir
4048
4049         test_mkdir $DIR/$tdir
4050         $LFS mkdir -i $MDTIDX $remote_dir ||
4051                 error "create remote directory failed"
4052
4053         touch $remote_dir/$tfile
4054         chmod 444 $remote_dir/$tfile
4055         chown $RUNAS_ID $remote_dir/$tfile
4056
4057         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4058
4059         chown $RUNAS_ID $remote_dir
4060         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4061                                         error "create" || true
4062         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4063                                     error "open RDWR" || true
4064         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4065 }
4066 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4067
4068 test_33e() {
4069         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4070
4071         mkdir $DIR/$tdir
4072
4073         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4074         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4075         mkdir $DIR/$tdir/local_dir
4076
4077         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4078         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4079         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4080
4081         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4082                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4083
4084         rmdir $DIR/$tdir/* || error "rmdir failed"
4085
4086         umask 777
4087         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4088         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4089         mkdir $DIR/$tdir/local_dir
4090
4091         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4092         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4093         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4094
4095         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4096                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4097
4098         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4099
4100         umask 000
4101         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4102         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4103         mkdir $DIR/$tdir/local_dir
4104
4105         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4106         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4107         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4108
4109         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4110                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4111 }
4112 run_test 33e "mkdir and striped directory should have same mode"
4113
4114 cleanup_33f() {
4115         trap 0
4116         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4117 }
4118
4119 test_33f() {
4120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4121         remote_mds_nodsh && skip "remote MDS with nodsh"
4122
4123         mkdir $DIR/$tdir
4124         chmod go+rwx $DIR/$tdir
4125         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4126         trap cleanup_33f EXIT
4127
4128         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4129                 error "cannot create striped directory"
4130
4131         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4132                 error "cannot create files in striped directory"
4133
4134         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4135                 error "cannot remove files in striped directory"
4136
4137         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4138                 error "cannot remove striped directory"
4139
4140         cleanup_33f
4141 }
4142 run_test 33f "nonroot user can create, access, and remove a striped directory"
4143
4144 test_33g() {
4145         mkdir -p $DIR/$tdir/dir2
4146
4147         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4148         echo $err
4149         [[ $err =~ "exists" ]] || error "Not exists error"
4150 }
4151 run_test 33g "nonroot user create already existing root created file"
4152
4153 test_33h() {
4154         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4155         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4156                 skip "Need MDS version at least 2.13.50"
4157
4158         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4159                 error "mkdir $tdir failed"
4160         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4161
4162         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4163         local index2
4164
4165         for fname in $DIR/$tdir/$tfile.bak \
4166                      $DIR/$tdir/$tfile.SAV \
4167                      $DIR/$tdir/$tfile.orig \
4168                      $DIR/$tdir/$tfile~; do
4169                 touch $fname  || error "touch $fname failed"
4170                 index2=$($LFS getstripe -m $fname)
4171                 [ $index -eq $index2 ] ||
4172                         error "$fname MDT index mismatch $index != $index2"
4173         done
4174
4175         local failed=0
4176         for i in {1..250}; do
4177                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4178                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4179                         touch $fname  || error "touch $fname failed"
4180                         index2=$($LFS getstripe -m $fname)
4181                         if [[ $index != $index2 ]]; then
4182                                 failed=$((failed + 1))
4183                                 echo "$fname MDT index mismatch $index != $index2"
4184                         fi
4185                 done
4186         done
4187         echo "$failed MDT index mismatches"
4188         (( failed < 20 )) || error "MDT index mismatch $failed times"
4189
4190 }
4191 run_test 33h "temp file is located on the same MDT as target"
4192
4193 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4194 test_34a() {
4195         rm -f $DIR/f34
4196         $MCREATE $DIR/f34 || error "mcreate failed"
4197         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4198                 error "getstripe failed"
4199         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4200         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4201                 error "getstripe failed"
4202         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4203                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4204 }
4205 run_test 34a "truncate file that has not been opened ==========="
4206
4207 test_34b() {
4208         [ ! -f $DIR/f34 ] && test_34a
4209         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4210                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4211         $OPENFILE -f O_RDONLY $DIR/f34
4212         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4213                 error "getstripe failed"
4214         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4215                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4216 }
4217 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4218
4219 test_34c() {
4220         [ ! -f $DIR/f34 ] && test_34a
4221         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4222                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4223         $OPENFILE -f O_RDWR $DIR/f34
4224         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4225                 error "$LFS getstripe failed"
4226         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4227                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4228 }
4229 run_test 34c "O_RDWR opening file-with-size works =============="
4230
4231 test_34d() {
4232         [ ! -f $DIR/f34 ] && test_34a
4233         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4234                 error "dd failed"
4235         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4236                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4237         rm $DIR/f34
4238 }
4239 run_test 34d "write to sparse file ============================="
4240
4241 test_34e() {
4242         rm -f $DIR/f34e
4243         $MCREATE $DIR/f34e || error "mcreate failed"
4244         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4245         $CHECKSTAT -s 1000 $DIR/f34e ||
4246                 error "Size of $DIR/f34e not equal to 1000 bytes"
4247         $OPENFILE -f O_RDWR $DIR/f34e
4248         $CHECKSTAT -s 1000 $DIR/f34e ||
4249                 error "Size of $DIR/f34e not equal to 1000 bytes"
4250 }
4251 run_test 34e "create objects, some with size and some without =="
4252
4253 test_34f() { # bug 6242, 6243
4254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4255
4256         SIZE34F=48000
4257         rm -f $DIR/f34f
4258         $MCREATE $DIR/f34f || error "mcreate failed"
4259         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4260         dd if=$DIR/f34f of=$TMP/f34f
4261         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4262         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4263         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4264         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4265         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4266 }
4267 run_test 34f "read from a file with no objects until EOF ======="
4268
4269 test_34g() {
4270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4271
4272         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4273                 error "dd failed"
4274         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4275         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4276                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4277         cancel_lru_locks osc
4278         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4279                 error "wrong size after lock cancel"
4280
4281         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4282         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4283                 error "expanding truncate failed"
4284         cancel_lru_locks osc
4285         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4286                 error "wrong expanded size after lock cancel"
4287 }
4288 run_test 34g "truncate long file ==============================="
4289
4290 test_34h() {
4291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4292
4293         local gid=10
4294         local sz=1000
4295
4296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4297         sync # Flush the cache so that multiop below does not block on cache
4298              # flush when getting the group lock
4299         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4300         MULTIPID=$!
4301
4302         # Since just timed wait is not good enough, let's do a sync write
4303         # that way we are sure enough time for a roundtrip + processing
4304         # passed + 2 seconds of extra margin.
4305         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4306         rm $DIR/${tfile}-1
4307         sleep 2
4308
4309         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4310                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4311                 kill -9 $MULTIPID
4312         fi
4313         wait $MULTIPID
4314         local nsz=`stat -c %s $DIR/$tfile`
4315         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4316 }
4317 run_test 34h "ftruncate file under grouplock should not block"
4318
4319 test_35a() {
4320         cp /bin/sh $DIR/f35a
4321         chmod 444 $DIR/f35a
4322         chown $RUNAS_ID $DIR/f35a
4323         $RUNAS $DIR/f35a && error || true
4324         rm $DIR/f35a
4325 }
4326 run_test 35a "exec file with mode 444 (should return and not leak)"
4327
4328 test_36a() {
4329         rm -f $DIR/f36
4330         utime $DIR/f36 || error "utime failed for MDS"
4331 }
4332 run_test 36a "MDS utime check (mknod, utime)"
4333
4334 test_36b() {
4335         echo "" > $DIR/f36
4336         utime $DIR/f36 || error "utime failed for OST"
4337 }
4338 run_test 36b "OST utime check (open, utime)"
4339
4340 test_36c() {
4341         rm -f $DIR/d36/f36
4342         test_mkdir $DIR/d36
4343         chown $RUNAS_ID $DIR/d36
4344         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4345 }
4346 run_test 36c "non-root MDS utime check (mknod, utime)"
4347
4348 test_36d() {
4349         [ ! -d $DIR/d36 ] && test_36c
4350         echo "" > $DIR/d36/f36
4351         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4352 }
4353 run_test 36d "non-root OST utime check (open, utime)"
4354
4355 test_36e() {
4356         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4357
4358         test_mkdir $DIR/$tdir
4359         touch $DIR/$tdir/$tfile
4360         $RUNAS utime $DIR/$tdir/$tfile &&
4361                 error "utime worked, expected failure" || true
4362 }
4363 run_test 36e "utime on non-owned file (should return error)"
4364
4365 subr_36fh() {
4366         local fl="$1"
4367         local LANG_SAVE=$LANG
4368         local LC_LANG_SAVE=$LC_LANG
4369         export LANG=C LC_LANG=C # for date language
4370
4371         DATESTR="Dec 20  2000"
4372         test_mkdir $DIR/$tdir
4373         lctl set_param fail_loc=$fl
4374         date; date +%s
4375         cp /etc/hosts $DIR/$tdir/$tfile
4376         sync & # write RPC generated with "current" inode timestamp, but delayed
4377         sleep 1
4378         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4379         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4380         cancel_lru_locks $OSC
4381         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4382         date; date +%s
4383         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4384                 echo "BEFORE: $LS_BEFORE" && \
4385                 echo "AFTER : $LS_AFTER" && \
4386                 echo "WANT  : $DATESTR" && \
4387                 error "$DIR/$tdir/$tfile timestamps changed" || true
4388
4389         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4390 }
4391
4392 test_36f() {
4393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4394
4395         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4396         subr_36fh "0x80000214"
4397 }
4398 run_test 36f "utime on file racing with OST BRW write =========="
4399
4400 test_36g() {
4401         remote_ost_nodsh && skip "remote OST with nodsh"
4402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4403         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4404                 skip "Need MDS version at least 2.12.51"
4405
4406         local fmd_max_age
4407         local fmd
4408         local facet="ost1"
4409         local tgt="obdfilter"
4410
4411         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4412
4413         test_mkdir $DIR/$tdir
4414         fmd_max_age=$(do_facet $facet \
4415                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4416                 head -n 1")
4417
4418         echo "FMD max age: ${fmd_max_age}s"
4419         touch $DIR/$tdir/$tfile
4420         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4421                 gawk '{cnt=cnt+$1}  END{print cnt}')
4422         echo "FMD before: $fmd"
4423         [[ $fmd == 0 ]] &&
4424                 error "FMD wasn't create by touch"
4425         sleep $((fmd_max_age + 12))
4426         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4427                 gawk '{cnt=cnt+$1}  END{print cnt}')
4428         echo "FMD after: $fmd"
4429         [[ $fmd == 0 ]] ||
4430                 error "FMD wasn't expired by ping"
4431 }
4432 run_test 36g "FMD cache expiry ====================="
4433
4434 test_36h() {
4435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4436
4437         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4438         subr_36fh "0x80000227"
4439 }
4440 run_test 36h "utime on file racing with OST BRW write =========="
4441
4442 test_36i() {
4443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4444
4445         test_mkdir $DIR/$tdir
4446         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4447
4448         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4449         local new_mtime=$((mtime + 200))
4450
4451         #change Modify time of striped dir
4452         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4453                         error "change mtime failed"
4454
4455         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4456
4457         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4458 }
4459 run_test 36i "change mtime on striped directory"
4460
4461 # test_37 - duplicate with tests 32q 32r
4462
4463 test_38() {
4464         local file=$DIR/$tfile
4465         touch $file
4466         openfile -f O_DIRECTORY $file
4467         local RC=$?
4468         local ENOTDIR=20
4469         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4470         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4471 }
4472 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4473
4474 test_39a() { # was test_39
4475         touch $DIR/$tfile
4476         touch $DIR/${tfile}2
4477 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4478 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4479 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4480         sleep 2
4481         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4482         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4483                 echo "mtime"
4484                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4485                 echo "atime"
4486                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4487                 echo "ctime"
4488                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4489                 error "O_TRUNC didn't change timestamps"
4490         fi
4491 }
4492 run_test 39a "mtime changed on create"
4493
4494 test_39b() {
4495         test_mkdir -c1 $DIR/$tdir
4496         cp -p /etc/passwd $DIR/$tdir/fopen
4497         cp -p /etc/passwd $DIR/$tdir/flink
4498         cp -p /etc/passwd $DIR/$tdir/funlink
4499         cp -p /etc/passwd $DIR/$tdir/frename
4500         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4501
4502         sleep 1
4503         echo "aaaaaa" >> $DIR/$tdir/fopen
4504         echo "aaaaaa" >> $DIR/$tdir/flink
4505         echo "aaaaaa" >> $DIR/$tdir/funlink
4506         echo "aaaaaa" >> $DIR/$tdir/frename
4507
4508         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4509         local link_new=`stat -c %Y $DIR/$tdir/flink`
4510         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4511         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4512
4513         cat $DIR/$tdir/fopen > /dev/null
4514         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4515         rm -f $DIR/$tdir/funlink2
4516         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4517
4518         for (( i=0; i < 2; i++ )) ; do
4519                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4520                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4521                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4522                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4523
4524                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4525                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4526                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4527                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4528
4529                 cancel_lru_locks $OSC
4530                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4531         done
4532 }
4533 run_test 39b "mtime change on open, link, unlink, rename  ======"
4534
4535 # this should be set to past
4536 TEST_39_MTIME=`date -d "1 year ago" +%s`
4537
4538 # bug 11063
4539 test_39c() {
4540         touch $DIR1/$tfile
4541         sleep 2
4542         local mtime0=`stat -c %Y $DIR1/$tfile`
4543
4544         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4545         local mtime1=`stat -c %Y $DIR1/$tfile`
4546         [ "$mtime1" = $TEST_39_MTIME ] || \
4547                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4548
4549         local d1=`date +%s`
4550         echo hello >> $DIR1/$tfile
4551         local d2=`date +%s`
4552         local mtime2=`stat -c %Y $DIR1/$tfile`
4553         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4554                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4555
4556         mv $DIR1/$tfile $DIR1/$tfile-1
4557
4558         for (( i=0; i < 2; i++ )) ; do
4559                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4560                 [ "$mtime2" = "$mtime3" ] || \
4561                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4562
4563                 cancel_lru_locks $OSC
4564                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4565         done
4566 }
4567 run_test 39c "mtime change on rename ==========================="
4568
4569 # bug 21114
4570 test_39d() {
4571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4572
4573         touch $DIR1/$tfile
4574         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4575
4576         for (( i=0; i < 2; i++ )) ; do
4577                 local mtime=`stat -c %Y $DIR1/$tfile`
4578                 [ $mtime = $TEST_39_MTIME ] || \
4579                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4580
4581                 cancel_lru_locks $OSC
4582                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4583         done
4584 }
4585 run_test 39d "create, utime, stat =============================="
4586
4587 # bug 21114
4588 test_39e() {
4589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4590
4591         touch $DIR1/$tfile
4592         local mtime1=`stat -c %Y $DIR1/$tfile`
4593
4594         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4595
4596         for (( i=0; i < 2; i++ )) ; do
4597                 local mtime2=`stat -c %Y $DIR1/$tfile`
4598                 [ $mtime2 = $TEST_39_MTIME ] || \
4599                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4600
4601                 cancel_lru_locks $OSC
4602                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4603         done
4604 }
4605 run_test 39e "create, stat, utime, stat ========================"
4606
4607 # bug 21114
4608 test_39f() {
4609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4610
4611         touch $DIR1/$tfile
4612         mtime1=`stat -c %Y $DIR1/$tfile`
4613
4614         sleep 2
4615         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4616
4617         for (( i=0; i < 2; i++ )) ; do
4618                 local mtime2=`stat -c %Y $DIR1/$tfile`
4619                 [ $mtime2 = $TEST_39_MTIME ] || \
4620                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4621
4622                 cancel_lru_locks $OSC
4623                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4624         done
4625 }
4626 run_test 39f "create, stat, sleep, utime, stat ================="
4627
4628 # bug 11063
4629 test_39g() {
4630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4631
4632         echo hello >> $DIR1/$tfile
4633         local mtime1=`stat -c %Y $DIR1/$tfile`
4634
4635         sleep 2
4636         chmod o+r $DIR1/$tfile
4637
4638         for (( i=0; i < 2; i++ )) ; do
4639                 local mtime2=`stat -c %Y $DIR1/$tfile`
4640                 [ "$mtime1" = "$mtime2" ] || \
4641                         error "lost mtime: $mtime2, should be $mtime1"
4642
4643                 cancel_lru_locks $OSC
4644                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4645         done
4646 }
4647 run_test 39g "write, chmod, stat ==============================="
4648
4649 # bug 11063
4650 test_39h() {
4651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4652
4653         touch $DIR1/$tfile
4654         sleep 1
4655
4656         local d1=`date`
4657         echo hello >> $DIR1/$tfile
4658         local mtime1=`stat -c %Y $DIR1/$tfile`
4659
4660         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4661         local d2=`date`
4662         if [ "$d1" != "$d2" ]; then
4663                 echo "write and touch not within one second"
4664         else
4665                 for (( i=0; i < 2; i++ )) ; do
4666                         local mtime2=`stat -c %Y $DIR1/$tfile`
4667                         [ "$mtime2" = $TEST_39_MTIME ] || \
4668                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4669
4670                         cancel_lru_locks $OSC
4671                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4672                 done
4673         fi
4674 }
4675 run_test 39h "write, utime within one second, stat ============="
4676
4677 test_39i() {
4678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4679
4680         touch $DIR1/$tfile
4681         sleep 1
4682
4683         echo hello >> $DIR1/$tfile
4684         local mtime1=`stat -c %Y $DIR1/$tfile`
4685
4686         mv $DIR1/$tfile $DIR1/$tfile-1
4687
4688         for (( i=0; i < 2; i++ )) ; do
4689                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4690
4691                 [ "$mtime1" = "$mtime2" ] || \
4692                         error "lost mtime: $mtime2, should be $mtime1"
4693
4694                 cancel_lru_locks $OSC
4695                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4696         done
4697 }
4698 run_test 39i "write, rename, stat =============================="
4699
4700 test_39j() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         start_full_debug_logging
4704         touch $DIR1/$tfile
4705         sleep 1
4706
4707         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4708         lctl set_param fail_loc=0x80000412
4709         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4710                 error "multiop failed"
4711         local multipid=$!
4712         local mtime1=`stat -c %Y $DIR1/$tfile`
4713
4714         mv $DIR1/$tfile $DIR1/$tfile-1
4715
4716         kill -USR1 $multipid
4717         wait $multipid || error "multiop close failed"
4718
4719         for (( i=0; i < 2; i++ )) ; do
4720                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4721                 [ "$mtime1" = "$mtime2" ] ||
4722                         error "mtime is lost on close: $mtime2, " \
4723                               "should be $mtime1"
4724
4725                 cancel_lru_locks
4726                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4727         done
4728         lctl set_param fail_loc=0
4729         stop_full_debug_logging
4730 }
4731 run_test 39j "write, rename, close, stat ======================="
4732
4733 test_39k() {
4734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4735
4736         touch $DIR1/$tfile
4737         sleep 1
4738
4739         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4740         local multipid=$!
4741         local mtime1=`stat -c %Y $DIR1/$tfile`
4742
4743         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4744
4745         kill -USR1 $multipid
4746         wait $multipid || error "multiop close failed"
4747
4748         for (( i=0; i < 2; i++ )) ; do
4749                 local mtime2=`stat -c %Y $DIR1/$tfile`
4750
4751                 [ "$mtime2" = $TEST_39_MTIME ] || \
4752                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4753
4754                 cancel_lru_locks
4755                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4756         done
4757 }
4758 run_test 39k "write, utime, close, stat ========================"
4759
4760 # this should be set to future
4761 TEST_39_ATIME=`date -d "1 year" +%s`
4762
4763 test_39l() {
4764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4765         remote_mds_nodsh && skip "remote MDS with nodsh"
4766
4767         local atime_diff=$(do_facet $SINGLEMDS \
4768                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4769         rm -rf $DIR/$tdir
4770         mkdir_on_mdt0 $DIR/$tdir
4771
4772         # test setting directory atime to future
4773         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4774         local atime=$(stat -c %X $DIR/$tdir)
4775         [ "$atime" = $TEST_39_ATIME ] ||
4776                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4777
4778         # test setting directory atime from future to now
4779         local now=$(date +%s)
4780         touch -a -d @$now $DIR/$tdir
4781
4782         atime=$(stat -c %X $DIR/$tdir)
4783         [ "$atime" -eq "$now"  ] ||
4784                 error "atime is not updated from future: $atime, $now"
4785
4786         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4787         sleep 3
4788
4789         # test setting directory atime when now > dir atime + atime_diff
4790         local d1=$(date +%s)
4791         ls $DIR/$tdir
4792         local d2=$(date +%s)
4793         cancel_lru_locks mdc
4794         atime=$(stat -c %X $DIR/$tdir)
4795         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4796                 error "atime is not updated  : $atime, should be $d2"
4797
4798         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4799         sleep 3
4800
4801         # test not setting directory atime when now < dir atime + atime_diff
4802         ls $DIR/$tdir
4803         cancel_lru_locks mdc
4804         atime=$(stat -c %X $DIR/$tdir)
4805         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4806                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4807
4808         do_facet $SINGLEMDS \
4809                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4810 }
4811 run_test 39l "directory atime update ==========================="
4812
4813 test_39m() {
4814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4815
4816         touch $DIR1/$tfile
4817         sleep 2
4818         local far_past_mtime=$(date -d "May 29 1953" +%s)
4819         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4820
4821         touch -m -d @$far_past_mtime $DIR1/$tfile
4822         touch -a -d @$far_past_atime $DIR1/$tfile
4823
4824         for (( i=0; i < 2; i++ )) ; do
4825                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4826                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4827                         error "atime or mtime set incorrectly"
4828
4829                 cancel_lru_locks $OSC
4830                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4831         done
4832 }
4833 run_test 39m "test atime and mtime before 1970"
4834
4835 test_39n() { # LU-3832
4836         remote_mds_nodsh && skip "remote MDS with nodsh"
4837
4838         local atime_diff=$(do_facet $SINGLEMDS \
4839                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4840         local atime0
4841         local atime1
4842         local atime2
4843
4844         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4845
4846         rm -rf $DIR/$tfile
4847         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4848         atime0=$(stat -c %X $DIR/$tfile)
4849
4850         sleep 5
4851         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4852         atime1=$(stat -c %X $DIR/$tfile)
4853
4854         sleep 5
4855         cancel_lru_locks mdc
4856         cancel_lru_locks osc
4857         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4858         atime2=$(stat -c %X $DIR/$tfile)
4859
4860         do_facet $SINGLEMDS \
4861                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4862
4863         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4864         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4865 }
4866 run_test 39n "check that O_NOATIME is honored"
4867
4868 test_39o() {
4869         TESTDIR=$DIR/$tdir/$tfile
4870         [ -e $TESTDIR ] && rm -rf $TESTDIR
4871         mkdir -p $TESTDIR
4872         cd $TESTDIR
4873         links1=2
4874         ls
4875         mkdir a b
4876         ls
4877         links2=$(stat -c %h .)
4878         [ $(($links1 + 2)) != $links2 ] &&
4879                 error "wrong links count $(($links1 + 2)) != $links2"
4880         rmdir b
4881         links3=$(stat -c %h .)
4882         [ $(($links1 + 1)) != $links3 ] &&
4883                 error "wrong links count $links1 != $links3"
4884         return 0
4885 }
4886 run_test 39o "directory cached attributes updated after create"
4887
4888 test_39p() {
4889         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4890
4891         local MDTIDX=1
4892         TESTDIR=$DIR/$tdir/$tdir
4893         [ -e $TESTDIR ] && rm -rf $TESTDIR
4894         test_mkdir -p $TESTDIR
4895         cd $TESTDIR
4896         links1=2
4897         ls
4898         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4899         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4900         ls
4901         links2=$(stat -c %h .)
4902         [ $(($links1 + 2)) != $links2 ] &&
4903                 error "wrong links count $(($links1 + 2)) != $links2"
4904         rmdir remote_dir2
4905         links3=$(stat -c %h .)
4906         [ $(($links1 + 1)) != $links3 ] &&
4907                 error "wrong links count $links1 != $links3"
4908         return 0
4909 }
4910 run_test 39p "remote directory cached attributes updated after create ========"
4911
4912 test_39r() {
4913         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4914                 skip "no atime update on old OST"
4915         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4916                 skip_env "ldiskfs only test"
4917         fi
4918
4919         local saved_adiff
4920         saved_adiff=$(do_facet ost1 \
4921                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4922         stack_trap "do_facet ost1 \
4923                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4924
4925         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4926
4927         $LFS setstripe -i 0 $DIR/$tfile
4928         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4929                 error "can't write initial file"
4930         cancel_lru_locks osc
4931
4932         # exceed atime_diff and access file
4933         sleep 6
4934         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4935                 error "can't udpate atime"
4936
4937         local atime_cli=$(stat -c %X $DIR/$tfile)
4938         echo "client atime: $atime_cli"
4939         # allow atime update to be written to device
4940         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4941         sleep 5
4942
4943         local ostdev=$(ostdevname 1)
4944         local fid=($(lfs getstripe -y $DIR/$tfile |
4945                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4946         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4947         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4948
4949         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4950         local atime_ost=$(do_facet ost1 "$cmd" |&
4951                           awk -F'[: ]' '/atime:/ { print $4 }')
4952         (( atime_cli == atime_ost )) ||
4953                 error "atime on client $atime_cli != ost $atime_ost"
4954 }
4955 run_test 39r "lazy atime update on OST"
4956
4957 test_39q() { # LU-8041
4958         local testdir=$DIR/$tdir
4959         mkdir -p $testdir
4960         multiop_bg_pause $testdir D_c || error "multiop failed"
4961         local multipid=$!
4962         cancel_lru_locks mdc
4963         kill -USR1 $multipid
4964         local atime=$(stat -c %X $testdir)
4965         [ "$atime" -ne 0 ] || error "atime is zero"
4966 }
4967 run_test 39q "close won't zero out atime"
4968
4969 test_40() {
4970         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4971         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4972                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4973         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4974                 error "$tfile is not 4096 bytes in size"
4975 }
4976 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4977
4978 test_41() {
4979         # bug 1553
4980         small_write $DIR/f41 18
4981 }
4982 run_test 41 "test small file write + fstat ====================="
4983
4984 count_ost_writes() {
4985         lctl get_param -n ${OSC}.*.stats |
4986                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4987                         END { printf("%0.0f", writes) }'
4988 }
4989
4990 # decent default
4991 WRITEBACK_SAVE=500
4992 DIRTY_RATIO_SAVE=40
4993 MAX_DIRTY_RATIO=50
4994 BG_DIRTY_RATIO_SAVE=10
4995 MAX_BG_DIRTY_RATIO=25
4996
4997 start_writeback() {
4998         trap 0
4999         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5000         # dirty_ratio, dirty_background_ratio
5001         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5002                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5003                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5004                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5005         else
5006                 # if file not here, we are a 2.4 kernel
5007                 kill -CONT `pidof kupdated`
5008         fi
5009 }
5010
5011 stop_writeback() {
5012         # setup the trap first, so someone cannot exit the test at the
5013         # exact wrong time and mess up a machine
5014         trap start_writeback EXIT
5015         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5016         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5017                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5018                 sysctl -w vm.dirty_writeback_centisecs=0
5019                 sysctl -w vm.dirty_writeback_centisecs=0
5020                 # save and increase /proc/sys/vm/dirty_ratio
5021                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5022                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5023                 # save and increase /proc/sys/vm/dirty_background_ratio
5024                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5025                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5026         else
5027                 # if file not here, we are a 2.4 kernel
5028                 kill -STOP `pidof kupdated`
5029         fi
5030 }
5031
5032 # ensure that all stripes have some grant before we test client-side cache
5033 setup_test42() {
5034         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5035                 dd if=/dev/zero of=$i bs=4k count=1
5036                 rm $i
5037         done
5038 }
5039
5040 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5041 # file truncation, and file removal.
5042 test_42a() {
5043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5044
5045         setup_test42
5046         cancel_lru_locks $OSC
5047         stop_writeback
5048         sync; sleep 1; sync # just to be safe
5049         BEFOREWRITES=`count_ost_writes`
5050         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5051         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5052         AFTERWRITES=`count_ost_writes`
5053         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5054                 error "$BEFOREWRITES < $AFTERWRITES"
5055         start_writeback
5056 }
5057 run_test 42a "ensure that we don't flush on close"
5058
5059 test_42b() {
5060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5061
5062         setup_test42
5063         cancel_lru_locks $OSC
5064         stop_writeback
5065         sync
5066         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5067         BEFOREWRITES=$(count_ost_writes)
5068         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5069         AFTERWRITES=$(count_ost_writes)
5070         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5071                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5072         fi
5073         BEFOREWRITES=$(count_ost_writes)
5074         sync || error "sync: $?"
5075         AFTERWRITES=$(count_ost_writes)
5076         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5077                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5078         fi
5079         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5080         start_writeback
5081         return 0
5082 }
5083 run_test 42b "test destroy of file with cached dirty data ======"
5084
5085 # if these tests just want to test the effect of truncation,
5086 # they have to be very careful.  consider:
5087 # - the first open gets a {0,EOF}PR lock
5088 # - the first write conflicts and gets a {0, count-1}PW
5089 # - the rest of the writes are under {count,EOF}PW
5090 # - the open for truncate tries to match a {0,EOF}PR
5091 #   for the filesize and cancels the PWs.
5092 # any number of fixes (don't get {0,EOF} on open, match
5093 # composite locks, do smarter file size management) fix
5094 # this, but for now we want these tests to verify that
5095 # the cancellation with truncate intent works, so we
5096 # start the file with a full-file pw lock to match against
5097 # until the truncate.
5098 trunc_test() {
5099         test=$1
5100         file=$DIR/$test
5101         offset=$2
5102         cancel_lru_locks $OSC
5103         stop_writeback
5104         # prime the file with 0,EOF PW to match
5105         touch $file
5106         $TRUNCATE $file 0
5107         sync; sync
5108         # now the real test..
5109         dd if=/dev/zero of=$file bs=1024 count=100
5110         BEFOREWRITES=`count_ost_writes`
5111         $TRUNCATE $file $offset
5112         cancel_lru_locks $OSC
5113         AFTERWRITES=`count_ost_writes`
5114         start_writeback
5115 }
5116
5117 test_42c() {
5118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5119
5120         trunc_test 42c 1024
5121         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5122                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5123         rm $file
5124 }
5125 run_test 42c "test partial truncate of file with cached dirty data"
5126
5127 test_42d() {
5128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5129
5130         trunc_test 42d 0
5131         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5132                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5133         rm $file
5134 }
5135 run_test 42d "test complete truncate of file with cached dirty data"
5136
5137 test_42e() { # bug22074
5138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5139
5140         local TDIR=$DIR/${tdir}e
5141         local pages=16 # hardcoded 16 pages, don't change it.
5142         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5143         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5144         local max_dirty_mb
5145         local warmup_files
5146
5147         test_mkdir $DIR/${tdir}e
5148         $LFS setstripe -c 1 $TDIR
5149         createmany -o $TDIR/f $files
5150
5151         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5152
5153         # we assume that with $OSTCOUNT files, at least one of them will
5154         # be allocated on OST0.
5155         warmup_files=$((OSTCOUNT * max_dirty_mb))
5156         createmany -o $TDIR/w $warmup_files
5157
5158         # write a large amount of data into one file and sync, to get good
5159         # avail_grant number from OST.
5160         for ((i=0; i<$warmup_files; i++)); do
5161                 idx=$($LFS getstripe -i $TDIR/w$i)
5162                 [ $idx -ne 0 ] && continue
5163                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5164                 break
5165         done
5166         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5167         sync
5168         $LCTL get_param $proc_osc0/cur_dirty_bytes
5169         $LCTL get_param $proc_osc0/cur_grant_bytes
5170
5171         # create as much dirty pages as we can while not to trigger the actual
5172         # RPCs directly. but depends on the env, VFS may trigger flush during this
5173         # period, hopefully we are good.
5174         for ((i=0; i<$warmup_files; i++)); do
5175                 idx=$($LFS getstripe -i $TDIR/w$i)
5176                 [ $idx -ne 0 ] && continue
5177                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5178         done
5179         $LCTL get_param $proc_osc0/cur_dirty_bytes
5180         $LCTL get_param $proc_osc0/cur_grant_bytes
5181
5182         # perform the real test
5183         $LCTL set_param $proc_osc0/rpc_stats 0
5184         for ((;i<$files; i++)); do
5185                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5186                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5187         done
5188         sync
5189         $LCTL get_param $proc_osc0/rpc_stats
5190
5191         local percent=0
5192         local have_ppr=false
5193         $LCTL get_param $proc_osc0/rpc_stats |
5194                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5195                         # skip lines until we are at the RPC histogram data
5196                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5197                         $have_ppr || continue
5198
5199                         # we only want the percent stat for < 16 pages
5200                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5201
5202                         percent=$((percent + WPCT))
5203                         if [[ $percent -gt 15 ]]; then
5204                                 error "less than 16-pages write RPCs" \
5205                                       "$percent% > 15%"
5206                                 break
5207                         fi
5208                 done
5209         rm -rf $TDIR
5210 }
5211 run_test 42e "verify sub-RPC writes are not done synchronously"
5212
5213 test_43A() { # was test_43
5214         test_mkdir $DIR/$tdir
5215         cp -p /bin/ls $DIR/$tdir/$tfile
5216         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5217         pid=$!
5218         # give multiop a chance to open
5219         sleep 1
5220
5221         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5222         kill -USR1 $pid
5223         # Wait for multiop to exit
5224         wait $pid
5225 }
5226 run_test 43A "execution of file opened for write should return -ETXTBSY"
5227
5228 test_43a() {
5229         test_mkdir $DIR/$tdir
5230         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5231         $DIR/$tdir/sleep 60 &
5232         SLEEP_PID=$!
5233         # Make sure exec of $tdir/sleep wins race with truncate
5234         sleep 1
5235         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5236         kill $SLEEP_PID
5237 }
5238 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5239
5240 test_43b() {
5241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5242
5243         test_mkdir $DIR/$tdir
5244         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5245         $DIR/$tdir/sleep 60 &
5246         SLEEP_PID=$!
5247         # Make sure exec of $tdir/sleep wins race with truncate
5248         sleep 1
5249         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5250         kill $SLEEP_PID
5251 }
5252 run_test 43b "truncate of file being executed should return -ETXTBSY"
5253
5254 test_43c() {
5255         local testdir="$DIR/$tdir"
5256         test_mkdir $testdir
5257         cp $SHELL $testdir/
5258         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5259                 ( cd $testdir && md5sum -c )
5260 }
5261 run_test 43c "md5sum of copy into lustre"
5262
5263 test_44A() { # was test_44
5264         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5265
5266         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5267         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5268 }
5269 run_test 44A "zero length read from a sparse stripe"
5270
5271 test_44a() {
5272         local nstripe=$($LFS getstripe -c -d $DIR)
5273         [ -z "$nstripe" ] && skip "can't get stripe info"
5274         [[ $nstripe -gt $OSTCOUNT ]] &&
5275                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5276
5277         local stride=$($LFS getstripe -S -d $DIR)
5278         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5279                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5280         fi
5281
5282         OFFSETS="0 $((stride/2)) $((stride-1))"
5283         for offset in $OFFSETS; do
5284                 for i in $(seq 0 $((nstripe-1))); do
5285                         local GLOBALOFFSETS=""
5286                         # size in Bytes
5287                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5288                         local myfn=$DIR/d44a-$size
5289                         echo "--------writing $myfn at $size"
5290                         ll_sparseness_write $myfn $size ||
5291                                 error "ll_sparseness_write"
5292                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5293                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5294                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5295
5296                         for j in $(seq 0 $((nstripe-1))); do
5297                                 # size in Bytes
5298                                 size=$((((j + $nstripe )*$stride + $offset)))
5299                                 ll_sparseness_write $myfn $size ||
5300                                         error "ll_sparseness_write"
5301                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5302                         done
5303                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5304                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5305                         rm -f $myfn
5306                 done
5307         done
5308 }
5309 run_test 44a "test sparse pwrite ==============================="
5310
5311 dirty_osc_total() {
5312         tot=0
5313         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5314                 tot=$(($tot + $d))
5315         done
5316         echo $tot
5317 }
5318 do_dirty_record() {
5319         before=`dirty_osc_total`
5320         echo executing "\"$*\""
5321         eval $*
5322         after=`dirty_osc_total`
5323         echo before $before, after $after
5324 }
5325 test_45() {
5326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5327
5328         f="$DIR/f45"
5329         # Obtain grants from OST if it supports it
5330         echo blah > ${f}_grant
5331         stop_writeback
5332         sync
5333         do_dirty_record "echo blah > $f"
5334         [[ $before -eq $after ]] && error "write wasn't cached"
5335         do_dirty_record "> $f"
5336         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5337         do_dirty_record "echo blah > $f"
5338         [[ $before -eq $after ]] && error "write wasn't cached"
5339         do_dirty_record "sync"
5340         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5341         do_dirty_record "echo blah > $f"
5342         [[ $before -eq $after ]] && error "write wasn't cached"
5343         do_dirty_record "cancel_lru_locks osc"
5344         [[ $before -gt $after ]] ||
5345                 error "lock cancellation didn't lower dirty count"
5346         start_writeback
5347 }
5348 run_test 45 "osc io page accounting ============================"
5349
5350 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5351 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5352 # objects offset and an assert hit when an rpc was built with 1023's mapped
5353 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5354 test_46() {
5355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5356
5357         f="$DIR/f46"
5358         stop_writeback
5359         sync
5360         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5361         sync
5362         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5363         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5364         sync
5365         start_writeback
5366 }
5367 run_test 46 "dirtying a previously written page ================"
5368
5369 # test_47 is removed "Device nodes check" is moved to test_28
5370
5371 test_48a() { # bug 2399
5372         [ "$mds1_FSTYPE" = "zfs" ] &&
5373         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5374                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5375
5376         test_mkdir $DIR/$tdir
5377         cd $DIR/$tdir
5378         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5379         test_mkdir $DIR/$tdir
5380         touch foo || error "'touch foo' failed after recreating cwd"
5381         test_mkdir bar
5382         touch .foo || error "'touch .foo' failed after recreating cwd"
5383         test_mkdir .bar
5384         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5385         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5386         cd . || error "'cd .' failed after recreating cwd"
5387         mkdir . && error "'mkdir .' worked after recreating cwd"
5388         rmdir . && error "'rmdir .' worked after recreating cwd"
5389         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5390         cd .. || error "'cd ..' failed after recreating cwd"
5391 }
5392 run_test 48a "Access renamed working dir (should return errors)="
5393
5394 test_48b() { # bug 2399
5395         rm -rf $DIR/$tdir
5396         test_mkdir $DIR/$tdir
5397         cd $DIR/$tdir
5398         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5399         touch foo && error "'touch foo' worked after removing cwd"
5400         mkdir foo && error "'mkdir foo' worked after removing cwd"
5401         touch .foo && error "'touch .foo' worked after removing cwd"
5402         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5403         ls . > /dev/null && error "'ls .' worked after removing cwd"
5404         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5405         mkdir . && error "'mkdir .' worked after removing cwd"
5406         rmdir . && error "'rmdir .' worked after removing cwd"
5407         ln -s . foo && error "'ln -s .' worked after removing cwd"
5408         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5409 }
5410 run_test 48b "Access removed working dir (should return errors)="
5411
5412 test_48c() { # bug 2350
5413         #lctl set_param debug=-1
5414         #set -vx
5415         rm -rf $DIR/$tdir
5416         test_mkdir -p $DIR/$tdir/dir
5417         cd $DIR/$tdir/dir
5418         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5419         $TRACE touch foo && error "touch foo worked after removing cwd"
5420         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5421         touch .foo && error "touch .foo worked after removing cwd"
5422         mkdir .foo && error "mkdir .foo worked after removing cwd"
5423         $TRACE ls . && error "'ls .' worked after removing cwd"
5424         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5425         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5426         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5427         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5428         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5429 }
5430 run_test 48c "Access removed working subdir (should return errors)"
5431
5432 test_48d() { # bug 2350
5433         #lctl set_param debug=-1
5434         #set -vx
5435         rm -rf $DIR/$tdir
5436         test_mkdir -p $DIR/$tdir/dir
5437         cd $DIR/$tdir/dir
5438         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5439         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5440         $TRACE touch foo && error "'touch foo' worked after removing parent"
5441         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5442         touch .foo && error "'touch .foo' worked after removing parent"
5443         mkdir .foo && error "mkdir .foo worked after removing parent"
5444         $TRACE ls . && error "'ls .' worked after removing parent"
5445         $TRACE ls .. && error "'ls ..' worked after removing parent"
5446         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5447         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5448         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5449         true
5450 }
5451 run_test 48d "Access removed parent subdir (should return errors)"
5452
5453 test_48e() { # bug 4134
5454         #lctl set_param debug=-1
5455         #set -vx
5456         rm -rf $DIR/$tdir
5457         test_mkdir -p $DIR/$tdir/dir
5458         cd $DIR/$tdir/dir
5459         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5460         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5461         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5462         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5463         # On a buggy kernel addition of "touch foo" after cd .. will
5464         # produce kernel oops in lookup_hash_it
5465         touch ../foo && error "'cd ..' worked after recreate parent"
5466         cd $DIR
5467         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5468 }
5469 run_test 48e "Access to recreated parent subdir (should return errors)"
5470
5471 test_48f() {
5472         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5473                 skip "need MDS >= 2.13.55"
5474         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5475         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5476                 skip "needs different host for mdt1 mdt2"
5477         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5478
5479         $LFS mkdir -i0 $DIR/$tdir
5480         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5481
5482         for d in sub1 sub2 sub3; do
5483                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5484                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5485                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5486         done
5487
5488         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5489 }
5490 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5491
5492 test_49() { # LU-1030
5493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5494         remote_ost_nodsh && skip "remote OST with nodsh"
5495
5496         # get ost1 size - $FSNAME-OST0000
5497         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5498                 awk '{ print $4 }')
5499         # write 800M at maximum
5500         [[ $ost1_size -lt 2 ]] && ost1_size=2
5501         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5502
5503         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5504         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5505         local dd_pid=$!
5506
5507         # change max_pages_per_rpc while writing the file
5508         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5509         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5510         # loop until dd process exits
5511         while ps ax -opid | grep -wq $dd_pid; do
5512                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5513                 sleep $((RANDOM % 5 + 1))
5514         done
5515         # restore original max_pages_per_rpc
5516         $LCTL set_param $osc1_mppc=$orig_mppc
5517         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5518 }
5519 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5520
5521 test_50() {
5522         # bug 1485
5523         test_mkdir $DIR/$tdir
5524         cd $DIR/$tdir
5525         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5526 }
5527 run_test 50 "special situations: /proc symlinks  ==============="
5528
5529 test_51a() {    # was test_51
5530         # bug 1516 - create an empty entry right after ".." then split dir
5531         test_mkdir -c1 $DIR/$tdir
5532         touch $DIR/$tdir/foo
5533         $MCREATE $DIR/$tdir/bar
5534         rm $DIR/$tdir/foo
5535         createmany -m $DIR/$tdir/longfile 201
5536         FNUM=202
5537         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5538                 $MCREATE $DIR/$tdir/longfile$FNUM
5539                 FNUM=$(($FNUM + 1))
5540                 echo -n "+"
5541         done
5542         echo
5543         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5544 }
5545 run_test 51a "special situations: split htree with empty entry =="
5546
5547 cleanup_print_lfs_df () {
5548         trap 0
5549         $LFS df
5550         $LFS df -i
5551 }
5552
5553 test_51b() {
5554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5555
5556         local dir=$DIR/$tdir
5557         local nrdirs=$((65536 + 100))
5558
5559         # cleanup the directory
5560         rm -fr $dir
5561
5562         test_mkdir -c1 $dir
5563
5564         $LFS df
5565         $LFS df -i
5566         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5567         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5568         [[ $numfree -lt $nrdirs ]] &&
5569                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5570
5571         # need to check free space for the directories as well
5572         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5573         numfree=$(( blkfree / $(fs_inode_ksize) ))
5574         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5575
5576         trap cleanup_print_lfs_df EXIT
5577
5578         # create files
5579         createmany -d $dir/d $nrdirs || {
5580                 unlinkmany $dir/d $nrdirs
5581                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5582         }
5583
5584         # really created :
5585         nrdirs=$(ls -U $dir | wc -l)
5586
5587         # unlink all but 100 subdirectories, then check it still works
5588         local left=100
5589         local delete=$((nrdirs - left))
5590
5591         $LFS df
5592         $LFS df -i
5593
5594         # for ldiskfs the nlink count should be 1, but this is OSD specific
5595         # and so this is listed for informational purposes only
5596         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5597         unlinkmany -d $dir/d $delete ||
5598                 error "unlink of first $delete subdirs failed"
5599
5600         echo "nlink between: $(stat -c %h $dir)"
5601         local found=$(ls -U $dir | wc -l)
5602         [ $found -ne $left ] &&
5603                 error "can't find subdirs: found only $found, expected $left"
5604
5605         unlinkmany -d $dir/d $delete $left ||
5606                 error "unlink of second $left subdirs failed"
5607         # regardless of whether the backing filesystem tracks nlink accurately
5608         # or not, the nlink count shouldn't be more than "." and ".." here
5609         local after=$(stat -c %h $dir)
5610         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5611                 echo "nlink after: $after"
5612
5613         cleanup_print_lfs_df
5614 }
5615 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5616
5617 test_51d() {
5618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5619         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5620
5621         test_mkdir $DIR/$tdir
5622         createmany -o $DIR/$tdir/t- 1000
5623         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5624         for N in $(seq 0 $((OSTCOUNT - 1))); do
5625                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5626                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5627                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5628                         '($1 == '$N') { objs += 1 } \
5629                         END { printf("%0.0f", objs) }')
5630                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5631         done
5632         unlinkmany $DIR/$tdir/t- 1000
5633
5634         NLAST=0
5635         for N in $(seq 1 $((OSTCOUNT - 1))); do
5636                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5637                         error "OST $N has less objects vs OST $NLAST" \
5638                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5639                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5640                         error "OST $N has less objects vs OST $NLAST" \
5641                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5642
5643                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5644                         error "OST $N has less #0 objects vs OST $NLAST" \
5645                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5646                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5647                         error "OST $N has less #0 objects vs OST $NLAST" \
5648                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5649                 NLAST=$N
5650         done
5651         rm -f $TMP/$tfile
5652 }
5653 run_test 51d "check object distribution"
5654
5655 test_51e() {
5656         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5657                 skip_env "ldiskfs only test"
5658         fi
5659
5660         test_mkdir -c1 $DIR/$tdir
5661         test_mkdir -c1 $DIR/$tdir/d0
5662
5663         touch $DIR/$tdir/d0/foo
5664         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5665                 error "file exceed 65000 nlink limit!"
5666         unlinkmany $DIR/$tdir/d0/f- 65001
5667         return 0
5668 }
5669 run_test 51e "check file nlink limit"
5670
5671 test_51f() {
5672         test_mkdir $DIR/$tdir
5673
5674         local max=100000
5675         local ulimit_old=$(ulimit -n)
5676         local spare=20 # number of spare fd's for scripts/libraries, etc.
5677         local mdt=$($LFS getstripe -m $DIR/$tdir)
5678         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5679
5680         echo "MDT$mdt numfree=$numfree, max=$max"
5681         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5682         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5683                 while ! ulimit -n $((numfree + spare)); do
5684                         numfree=$((numfree * 3 / 4))
5685                 done
5686                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5687         else
5688                 echo "left ulimit at $ulimit_old"
5689         fi
5690
5691         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5692                 unlinkmany $DIR/$tdir/f $numfree
5693                 error "create+open $numfree files in $DIR/$tdir failed"
5694         }
5695         ulimit -n $ulimit_old
5696
5697         # if createmany exits at 120s there will be fewer than $numfree files
5698         unlinkmany $DIR/$tdir/f $numfree || true
5699 }
5700 run_test 51f "check many open files limit"
5701
5702 test_52a() {
5703         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5704         test_mkdir $DIR/$tdir
5705         touch $DIR/$tdir/foo
5706         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5707         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5708         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5709         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5710         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5711                                         error "link worked"
5712         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5713         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5714         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5715                                                      error "lsattr"
5716         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5717         cp -r $DIR/$tdir $TMP/
5718         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5719 }
5720 run_test 52a "append-only flag test (should return errors)"
5721
5722 test_52b() {
5723         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5724         test_mkdir $DIR/$tdir
5725         touch $DIR/$tdir/foo
5726         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5727         cat test > $DIR/$tdir/foo && error "cat test worked"
5728         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5729         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5730         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5731                                         error "link worked"
5732         echo foo >> $DIR/$tdir/foo && error "echo worked"
5733         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5734         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5735         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5736         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5737                                                         error "lsattr"
5738         chattr -i $DIR/$tdir/foo || error "chattr failed"
5739
5740         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5741 }
5742 run_test 52b "immutable flag test (should return errors) ======="
5743
5744 test_53() {
5745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5746         remote_mds_nodsh && skip "remote MDS with nodsh"
5747         remote_ost_nodsh && skip "remote OST with nodsh"
5748
5749         local param
5750         local param_seq
5751         local ostname
5752         local mds_last
5753         local mds_last_seq
5754         local ost_last
5755         local ost_last_seq
5756         local ost_last_id
5757         local ostnum
5758         local node
5759         local found=false
5760         local support_last_seq=true
5761
5762         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5763                 support_last_seq=false
5764
5765         # only test MDT0000
5766         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5767         local value
5768         for value in $(do_facet $SINGLEMDS \
5769                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5770                 param=$(echo ${value[0]} | cut -d "=" -f1)
5771                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5772
5773                 if $support_last_seq; then
5774                         param_seq=$(echo $param |
5775                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5776                         mds_last_seq=$(do_facet $SINGLEMDS \
5777                                        $LCTL get_param -n $param_seq)
5778                 fi
5779                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5780
5781                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5782                 node=$(facet_active_host ost$((ostnum+1)))
5783                 param="obdfilter.$ostname.last_id"
5784                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5785                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5786                         ost_last_id=$ost_last
5787
5788                         if $support_last_seq; then
5789                                 ost_last_id=$(echo $ost_last |
5790                                               awk -F':' '{print $2}' |
5791                                               sed -e "s/^0x//g")
5792                                 ost_last_seq=$(echo $ost_last |
5793                                                awk -F':' '{print $1}')
5794                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5795                         fi
5796
5797                         if [[ $ost_last_id != $mds_last ]]; then
5798                                 error "$ost_last_id != $mds_last"
5799                         else
5800                                 found=true
5801                                 break
5802                         fi
5803                 done
5804         done
5805         $found || error "can not match last_seq/last_id for $mdtosc"
5806         return 0
5807 }
5808 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5809
5810 test_54a() {
5811         perl -MSocket -e ';' || skip "no Socket perl module installed"
5812
5813         $SOCKETSERVER $DIR/socket ||
5814                 error "$SOCKETSERVER $DIR/socket failed: $?"
5815         $SOCKETCLIENT $DIR/socket ||
5816                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5817         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5818 }
5819 run_test 54a "unix domain socket test =========================="
5820
5821 test_54b() {
5822         f="$DIR/f54b"
5823         mknod $f c 1 3
5824         chmod 0666 $f
5825         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5826 }
5827 run_test 54b "char device works in lustre ======================"
5828
5829 find_loop_dev() {
5830         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5831         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5832         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5833
5834         for i in $(seq 3 7); do
5835                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5836                 LOOPDEV=$LOOPBASE$i
5837                 LOOPNUM=$i
5838                 break
5839         done
5840 }
5841
5842 cleanup_54c() {
5843         local rc=0
5844         loopdev="$DIR/loop54c"
5845
5846         trap 0
5847         $UMOUNT $DIR/$tdir || rc=$?
5848         losetup -d $loopdev || true
5849         losetup -d $LOOPDEV || true
5850         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5851         return $rc
5852 }
5853
5854 test_54c() {
5855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5856
5857         loopdev="$DIR/loop54c"
5858
5859         find_loop_dev
5860         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5861         trap cleanup_54c EXIT
5862         mknod $loopdev b 7 $LOOPNUM
5863         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5864         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5865         losetup $loopdev $DIR/$tfile ||
5866                 error "can't set up $loopdev for $DIR/$tfile"
5867         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5868         test_mkdir $DIR/$tdir
5869         mount -t ext2 $loopdev $DIR/$tdir ||
5870                 error "error mounting $loopdev on $DIR/$tdir"
5871         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5872                 error "dd write"
5873         df $DIR/$tdir
5874         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5875                 error "dd read"
5876         cleanup_54c
5877 }
5878 run_test 54c "block device works in lustre ====================="
5879
5880 test_54d() {
5881         f="$DIR/f54d"
5882         string="aaaaaa"
5883         mknod $f p
5884         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5885 }
5886 run_test 54d "fifo device works in lustre ======================"
5887
5888 test_54e() {
5889         f="$DIR/f54e"
5890         string="aaaaaa"
5891         cp -aL /dev/console $f
5892         echo $string > $f || error "echo $string to $f failed"
5893 }
5894 run_test 54e "console/tty device works in lustre ======================"
5895
5896 test_56a() {
5897         local numfiles=3
5898         local numdirs=2
5899         local dir=$DIR/$tdir
5900
5901         rm -rf $dir
5902         test_mkdir -p $dir/dir
5903         for i in $(seq $numfiles); do
5904                 touch $dir/file$i
5905                 touch $dir/dir/file$i
5906         done
5907
5908         local numcomp=$($LFS getstripe --component-count $dir)
5909
5910         [[ $numcomp == 0 ]] && numcomp=1
5911
5912         # test lfs getstripe with --recursive
5913         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5914
5915         [[ $filenum -eq $((numfiles * 2)) ]] ||
5916                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5917         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5918         [[ $filenum -eq $numfiles ]] ||
5919                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5920         echo "$LFS getstripe showed obdidx or l_ost_idx"
5921
5922         # test lfs getstripe with file instead of dir
5923         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5924         [[ $filenum -eq 1 ]] ||
5925                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5926         echo "$LFS getstripe file1 passed"
5927
5928         #test lfs getstripe with --verbose
5929         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5930         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5931                 error "$LFS getstripe --verbose $dir: "\
5932                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5933         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5934                 error "$LFS getstripe $dir: showed lmm_magic"
5935
5936         #test lfs getstripe with -v prints lmm_fid
5937         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5938         local countfids=$((numdirs + numfiles * numcomp))
5939         [[ $filenum -eq $countfids ]] ||
5940                 error "$LFS getstripe -v $dir: "\
5941                       "got $filenum want $countfids lmm_fid"
5942         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5943                 error "$LFS getstripe $dir: showed lmm_fid by default"
5944         echo "$LFS getstripe --verbose passed"
5945
5946         #check for FID information
5947         local fid1=$($LFS getstripe --fid $dir/file1)
5948         local fid2=$($LFS getstripe --verbose $dir/file1 |
5949                      awk '/lmm_fid: / { print $2; exit; }')
5950         local fid3=$($LFS path2fid $dir/file1)
5951
5952         [ "$fid1" != "$fid2" ] &&
5953                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5954         [ "$fid1" != "$fid3" ] &&
5955                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5956         echo "$LFS getstripe --fid passed"
5957
5958         #test lfs getstripe with --obd
5959         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5960                 error "$LFS getstripe --obd wrong_uuid: should return error"
5961
5962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5963
5964         local ostidx=1
5965         local obduuid=$(ostuuid_from_index $ostidx)
5966         local found=$($LFS getstripe -r --obd $obduuid $dir |
5967                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5968
5969         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5970         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5971                 ((filenum--))
5972         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5973                 ((filenum--))
5974
5975         [[ $found -eq $filenum ]] ||
5976                 error "$LFS getstripe --obd: found $found expect $filenum"
5977         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5978                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5979                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5980                 error "$LFS getstripe --obd: should not show file on other obd"
5981         echo "$LFS getstripe --obd passed"
5982 }
5983 run_test 56a "check $LFS getstripe"
5984
5985 test_56b() {
5986         local dir=$DIR/$tdir
5987         local numdirs=3
5988
5989         test_mkdir $dir
5990         for i in $(seq $numdirs); do
5991                 test_mkdir $dir/dir$i
5992         done
5993
5994         # test lfs getdirstripe default mode is non-recursion, which is
5995         # different from lfs getstripe
5996         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5997
5998         [[ $dircnt -eq 1 ]] ||
5999                 error "$LFS getdirstripe: found $dircnt, not 1"
6000         dircnt=$($LFS getdirstripe --recursive $dir |
6001                 grep -c lmv_stripe_count)
6002         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6003                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6004 }
6005 run_test 56b "check $LFS getdirstripe"
6006
6007 test_56c() {
6008         remote_ost_nodsh && skip "remote OST with nodsh"
6009
6010         local ost_idx=0
6011         local ost_name=$(ostname_from_index $ost_idx)
6012         local old_status=$(ost_dev_status $ost_idx)
6013         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6014
6015         [[ -z "$old_status" ]] ||
6016                 skip_env "OST $ost_name is in $old_status status"
6017
6018         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6019         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6020                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6021         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6022                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6023                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6024         fi
6025
6026         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6027                 error "$LFS df -v showing inactive devices"
6028         sleep_maxage
6029
6030         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6031
6032         [[ "$new_status" =~ "D" ]] ||
6033                 error "$ost_name status is '$new_status', missing 'D'"
6034         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6035                 [[ "$new_status" =~ "N" ]] ||
6036                         error "$ost_name status is '$new_status', missing 'N'"
6037         fi
6038         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6039                 [[ "$new_status" =~ "f" ]] ||
6040                         error "$ost_name status is '$new_status', missing 'f'"
6041         fi
6042
6043         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6044         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6045                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6046         [[ -z "$p" ]] && restore_lustre_params < $p || true
6047         sleep_maxage
6048
6049         new_status=$(ost_dev_status $ost_idx)
6050         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6051                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6052         # can't check 'f' as devices may actually be on flash
6053 }
6054 run_test 56c "check 'lfs df' showing device status"
6055
6056 test_56d() {
6057         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6058         local osts=$($LFS df -v $MOUNT | grep -c OST)
6059
6060         $LFS df $MOUNT
6061
6062         (( mdts == MDSCOUNT )) ||
6063                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6064         (( osts == OSTCOUNT )) ||
6065                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6066 }
6067 run_test 56d "'lfs df -v' prints only configured devices"
6068
6069 NUMFILES=3
6070 NUMDIRS=3
6071 setup_56() {
6072         local local_tdir="$1"
6073         local local_numfiles="$2"
6074         local local_numdirs="$3"
6075         local dir_params="$4"
6076         local dir_stripe_params="$5"
6077
6078         if [ ! -d "$local_tdir" ] ; then
6079                 test_mkdir -p $dir_stripe_params $local_tdir
6080                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6081                 for i in $(seq $local_numfiles) ; do
6082                         touch $local_tdir/file$i
6083                 done
6084                 for i in $(seq $local_numdirs) ; do
6085                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6086                         for j in $(seq $local_numfiles) ; do
6087                                 touch $local_tdir/dir$i/file$j
6088                         done
6089                 done
6090         fi
6091 }
6092
6093 setup_56_special() {
6094         local local_tdir=$1
6095         local local_numfiles=$2
6096         local local_numdirs=$3
6097
6098         setup_56 $local_tdir $local_numfiles $local_numdirs
6099
6100         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6101                 for i in $(seq $local_numfiles) ; do
6102                         mknod $local_tdir/loop${i}b b 7 $i
6103                         mknod $local_tdir/null${i}c c 1 3
6104                         ln -s $local_tdir/file1 $local_tdir/link${i}
6105                 done
6106                 for i in $(seq $local_numdirs) ; do
6107                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6108                         mknod $local_tdir/dir$i/null${i}c c 1 3
6109                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6110                 done
6111         fi
6112 }
6113
6114 test_56g() {
6115         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6116         local expected=$(($NUMDIRS + 2))
6117
6118         setup_56 $dir $NUMFILES $NUMDIRS
6119
6120         # test lfs find with -name
6121         for i in $(seq $NUMFILES) ; do
6122                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6123
6124                 [ $nums -eq $expected ] ||
6125                         error "lfs find -name '*$i' $dir wrong: "\
6126                               "found $nums, expected $expected"
6127         done
6128 }
6129 run_test 56g "check lfs find -name"
6130
6131 test_56h() {
6132         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6133         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6134
6135         setup_56 $dir $NUMFILES $NUMDIRS
6136
6137         # test lfs find with ! -name
6138         for i in $(seq $NUMFILES) ; do
6139                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6140
6141                 [ $nums -eq $expected ] ||
6142                         error "lfs find ! -name '*$i' $dir wrong: "\
6143                               "found $nums, expected $expected"
6144         done
6145 }
6146 run_test 56h "check lfs find ! -name"
6147
6148 test_56i() {
6149         local dir=$DIR/$tdir
6150
6151         test_mkdir $dir
6152
6153         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6154         local out=$($cmd)
6155
6156         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6157 }
6158 run_test 56i "check 'lfs find -ost UUID' skips directories"
6159
6160 test_56j() {
6161         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6162
6163         setup_56_special $dir $NUMFILES $NUMDIRS
6164
6165         local expected=$((NUMDIRS + 1))
6166         local cmd="$LFS find -type d $dir"
6167         local nums=$($cmd | wc -l)
6168
6169         [ $nums -eq $expected ] ||
6170                 error "'$cmd' wrong: found $nums, expected $expected"
6171 }
6172 run_test 56j "check lfs find -type d"
6173
6174 test_56k() {
6175         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6176
6177         setup_56_special $dir $NUMFILES $NUMDIRS
6178
6179         local expected=$(((NUMDIRS + 1) * NUMFILES))
6180         local cmd="$LFS find -type f $dir"
6181         local nums=$($cmd | wc -l)
6182
6183         [ $nums -eq $expected ] ||
6184                 error "'$cmd' wrong: found $nums, expected $expected"
6185 }
6186 run_test 56k "check lfs find -type f"
6187
6188 test_56l() {
6189         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6190
6191         setup_56_special $dir $NUMFILES $NUMDIRS
6192
6193         local expected=$((NUMDIRS + NUMFILES))
6194         local cmd="$LFS find -type b $dir"
6195         local nums=$($cmd | wc -l)
6196
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199 }
6200 run_test 56l "check lfs find -type b"
6201
6202 test_56m() {
6203         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6204
6205         setup_56_special $dir $NUMFILES $NUMDIRS
6206
6207         local expected=$((NUMDIRS + NUMFILES))
6208         local cmd="$LFS find -type c $dir"
6209         local nums=$($cmd | wc -l)
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212 }
6213 run_test 56m "check lfs find -type c"
6214
6215 test_56n() {
6216         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6217         setup_56_special $dir $NUMFILES $NUMDIRS
6218
6219         local expected=$((NUMDIRS + NUMFILES))
6220         local cmd="$LFS find -type l $dir"
6221         local nums=$($cmd | wc -l)
6222
6223         [ $nums -eq $expected ] ||
6224                 error "'$cmd' wrong: found $nums, expected $expected"
6225 }
6226 run_test 56n "check lfs find -type l"
6227
6228 test_56o() {
6229         local dir=$DIR/$tdir
6230
6231         setup_56 $dir $NUMFILES $NUMDIRS
6232         utime $dir/file1 > /dev/null || error "utime (1)"
6233         utime $dir/file2 > /dev/null || error "utime (2)"
6234         utime $dir/dir1 > /dev/null || error "utime (3)"
6235         utime $dir/dir2 > /dev/null || error "utime (4)"
6236         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6237         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6238
6239         local expected=4
6240         local nums=$($LFS find -mtime +0 $dir | wc -l)
6241
6242         [ $nums -eq $expected ] ||
6243                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6244
6245         expected=12
6246         cmd="$LFS find -mtime 0 $dir"
6247         nums=$($cmd | wc -l)
6248         [ $nums -eq $expected ] ||
6249                 error "'$cmd' wrong: found $nums, expected $expected"
6250 }
6251 run_test 56o "check lfs find -mtime for old files"
6252
6253 test_56ob() {
6254         local dir=$DIR/$tdir
6255         local expected=1
6256         local count=0
6257
6258         # just to make sure there is something that won't be found
6259         test_mkdir $dir
6260         touch $dir/$tfile.now
6261
6262         for age in year week day hour min; do
6263                 count=$((count + 1))
6264
6265                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6266                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6267                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6268
6269                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6270                 local nums=$($cmd | wc -l)
6271                 [ $nums -eq $expected ] ||
6272                         error "'$cmd' wrong: found $nums, expected $expected"
6273
6274                 cmd="$LFS find $dir -atime $count${age:0:1}"
6275                 nums=$($cmd | wc -l)
6276                 [ $nums -eq $expected ] ||
6277                         error "'$cmd' wrong: found $nums, expected $expected"
6278         done
6279
6280         sleep 2
6281         cmd="$LFS find $dir -ctime +1s -type f"
6282         nums=$($cmd | wc -l)
6283         (( $nums == $count * 2 + 1)) ||
6284                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6285 }
6286 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6287
6288 test_newerXY_base() {
6289         local x=$1
6290         local y=$2
6291         local dir=$DIR/$tdir
6292         local ref
6293         local negref
6294
6295         if [ $y == "t" ]; then
6296                 if [ $x == "b" ]; then
6297                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6298                 else
6299                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6300                 fi
6301         else
6302                 ref=$DIR/$tfile.newer.$x$y
6303                 touch $ref || error "touch $ref failed"
6304         fi
6305
6306         echo "before = $ref"
6307         sleep 2
6308         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6309         sleep 2
6310         if [ $y == "t" ]; then
6311                 if [ $x == "b" ]; then
6312                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6313                 else
6314                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6315                 fi
6316         else
6317                 negref=$DIR/$tfile.negnewer.$x$y
6318                 touch $negref || error "touch $negref failed"
6319         fi
6320
6321         echo "after = $negref"
6322         local cmd="$LFS find $dir -newer$x$y $ref"
6323         local nums=$(eval $cmd | wc -l)
6324         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6325
6326         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6327                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6328
6329         cmd="$LFS find $dir ! -newer$x$y $negref"
6330         nums=$(eval $cmd | wc -l)
6331         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6332                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6333
6334         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6335         nums=$(eval $cmd | wc -l)
6336         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6337                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6338
6339         rm -rf $DIR/*
6340 }
6341
6342 test_56oc() {
6343         test_newerXY_base "a" "a"
6344         test_newerXY_base "a" "m"
6345         test_newerXY_base "a" "c"
6346         test_newerXY_base "m" "a"
6347         test_newerXY_base "m" "m"
6348         test_newerXY_base "m" "c"
6349         test_newerXY_base "c" "a"
6350         test_newerXY_base "c" "m"
6351         test_newerXY_base "c" "c"
6352
6353         [[ -n "$sles_version" ]] &&
6354                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6355
6356         test_newerXY_base "a" "t"
6357         test_newerXY_base "m" "t"
6358         test_newerXY_base "c" "t"
6359
6360         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6361            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6362                 ! btime_supported && echo "btime unsupported" && return 0
6363
6364         test_newerXY_base "b" "b"
6365         test_newerXY_base "b" "t"
6366 }
6367 run_test 56oc "check lfs find -newerXY work"
6368
6369 btime_supported() {
6370         local dir=$DIR/$tdir
6371         local rc
6372
6373         mkdir -p $dir
6374         touch $dir/$tfile
6375         $LFS find $dir -btime -1d -type f
6376         rc=$?
6377         rm -rf $dir
6378         return $rc
6379 }
6380
6381 test_56od() {
6382         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6383                 ! btime_supported && skip "btime unsupported on MDS"
6384
6385         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6386                 ! btime_supported && skip "btime unsupported on clients"
6387
6388         local dir=$DIR/$tdir
6389         local ref=$DIR/$tfile.ref
6390         local negref=$DIR/$tfile.negref
6391
6392         mkdir $dir || error "mkdir $dir failed"
6393         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6394         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6395         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6396         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6397         touch $ref || error "touch $ref failed"
6398         # sleep 3 seconds at least
6399         sleep 3
6400
6401         local before=$(do_facet mds1 date +%s)
6402         local skew=$(($(date +%s) - before + 1))
6403
6404         if (( skew < 0 && skew > -5 )); then
6405                 sleep $((0 - skew + 1))
6406                 skew=0
6407         fi
6408
6409         # Set the dir stripe params to limit files all on MDT0,
6410         # otherwise we need to calc the max clock skew between
6411         # the client and MDTs.
6412         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6413         sleep 2
6414         touch $negref || error "touch $negref failed"
6415
6416         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6417         local nums=$($cmd | wc -l)
6418         local expected=$(((NUMFILES + 1) * NUMDIRS))
6419
6420         [ $nums -eq $expected ] ||
6421                 error "'$cmd' wrong: found $nums, expected $expected"
6422
6423         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6424         nums=$($cmd | wc -l)
6425         expected=$((NUMFILES + 1))
6426         [ $nums -eq $expected ] ||
6427                 error "'$cmd' wrong: found $nums, expected $expected"
6428
6429         [ $skew -lt 0 ] && return
6430
6431         local after=$(do_facet mds1 date +%s)
6432         local age=$((after - before + 1 + skew))
6433
6434         cmd="$LFS find $dir -btime -${age}s -type f"
6435         nums=$($cmd | wc -l)
6436         expected=$(((NUMFILES + 1) * NUMDIRS))
6437
6438         echo "Clock skew between client and server: $skew, age:$age"
6439         [ $nums -eq $expected ] ||
6440                 error "'$cmd' wrong: found $nums, expected $expected"
6441
6442         expected=$(($NUMDIRS + 1))
6443         cmd="$LFS find $dir -btime -${age}s -type d"
6444         nums=$($cmd | wc -l)
6445         [ $nums -eq $expected ] ||
6446                 error "'$cmd' wrong: found $nums, expected $expected"
6447         rm -f $ref $negref || error "Failed to remove $ref $negref"
6448 }
6449 run_test 56od "check lfs find -btime with units"
6450
6451 test_56p() {
6452         [ $RUNAS_ID -eq $UID ] &&
6453                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6454
6455         local dir=$DIR/$tdir
6456
6457         setup_56 $dir $NUMFILES $NUMDIRS
6458         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6459
6460         local expected=$NUMFILES
6461         local cmd="$LFS find -uid $RUNAS_ID $dir"
6462         local nums=$($cmd | wc -l)
6463
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6468         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6469         nums=$($cmd | wc -l)
6470         [ $nums -eq $expected ] ||
6471                 error "'$cmd' wrong: found $nums, expected $expected"
6472 }
6473 run_test 56p "check lfs find -uid and ! -uid"
6474
6475 test_56q() {
6476         [ $RUNAS_ID -eq $UID ] &&
6477                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6478
6479         local dir=$DIR/$tdir
6480
6481         setup_56 $dir $NUMFILES $NUMDIRS
6482         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6483
6484         local expected=$NUMFILES
6485         local cmd="$LFS find -gid $RUNAS_GID $dir"
6486         local nums=$($cmd | wc -l)
6487
6488         [ $nums -eq $expected ] ||
6489                 error "'$cmd' wrong: found $nums, expected $expected"
6490
6491         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6492         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6493         nums=$($cmd | wc -l)
6494         [ $nums -eq $expected ] ||
6495                 error "'$cmd' wrong: found $nums, expected $expected"
6496 }
6497 run_test 56q "check lfs find -gid and ! -gid"
6498
6499 test_56r() {
6500         local dir=$DIR/$tdir
6501
6502         setup_56 $dir $NUMFILES $NUMDIRS
6503
6504         local expected=12
6505         local cmd="$LFS find -size 0 -type f -lazy $dir"
6506         local nums=$($cmd | wc -l)
6507
6508         [ $nums -eq $expected ] ||
6509                 error "'$cmd' wrong: found $nums, expected $expected"
6510         cmd="$LFS find -size 0 -type f $dir"
6511         nums=$($cmd | wc -l)
6512         [ $nums -eq $expected ] ||
6513                 error "'$cmd' wrong: found $nums, expected $expected"
6514
6515         expected=0
6516         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6517         nums=$($cmd | wc -l)
6518         [ $nums -eq $expected ] ||
6519                 error "'$cmd' wrong: found $nums, expected $expected"
6520         cmd="$LFS find ! -size 0 -type f $dir"
6521         nums=$($cmd | wc -l)
6522         [ $nums -eq $expected ] ||
6523                 error "'$cmd' wrong: found $nums, expected $expected"
6524
6525         echo "test" > $dir/$tfile
6526         echo "test2" > $dir/$tfile.2 && sync
6527         expected=1
6528         cmd="$LFS find -size 5 -type f -lazy $dir"
6529         nums=$($cmd | wc -l)
6530         [ $nums -eq $expected ] ||
6531                 error "'$cmd' wrong: found $nums, expected $expected"
6532         cmd="$LFS find -size 5 -type f $dir"
6533         nums=$($cmd | wc -l)
6534         [ $nums -eq $expected ] ||
6535                 error "'$cmd' wrong: found $nums, expected $expected"
6536
6537         expected=1
6538         cmd="$LFS find -size +5 -type f -lazy $dir"
6539         nums=$($cmd | wc -l)
6540         [ $nums -eq $expected ] ||
6541                 error "'$cmd' wrong: found $nums, expected $expected"
6542         cmd="$LFS find -size +5 -type f $dir"
6543         nums=$($cmd | wc -l)
6544         [ $nums -eq $expected ] ||
6545                 error "'$cmd' wrong: found $nums, expected $expected"
6546
6547         expected=2
6548         cmd="$LFS find -size +0 -type f -lazy $dir"
6549         nums=$($cmd | wc -l)
6550         [ $nums -eq $expected ] ||
6551                 error "'$cmd' wrong: found $nums, expected $expected"
6552         cmd="$LFS find -size +0 -type f $dir"
6553         nums=$($cmd | wc -l)
6554         [ $nums -eq $expected ] ||
6555                 error "'$cmd' wrong: found $nums, expected $expected"
6556
6557         expected=2
6558         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6559         nums=$($cmd | wc -l)
6560         [ $nums -eq $expected ] ||
6561                 error "'$cmd' wrong: found $nums, expected $expected"
6562         cmd="$LFS find ! -size -5 -type f $dir"
6563         nums=$($cmd | wc -l)
6564         [ $nums -eq $expected ] ||
6565                 error "'$cmd' wrong: found $nums, expected $expected"
6566
6567         expected=12
6568         cmd="$LFS find -size -5 -type f -lazy $dir"
6569         nums=$($cmd | wc -l)
6570         [ $nums -eq $expected ] ||
6571                 error "'$cmd' wrong: found $nums, expected $expected"
6572         cmd="$LFS find -size -5 -type f $dir"
6573         nums=$($cmd | wc -l)
6574         [ $nums -eq $expected ] ||
6575                 error "'$cmd' wrong: found $nums, expected $expected"
6576 }
6577 run_test 56r "check lfs find -size works"
6578
6579 test_56ra_sub() {
6580         local expected=$1
6581         local glimpses=$2
6582         local cmd="$3"
6583
6584         cancel_lru_locks $OSC
6585
6586         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6587         local nums=$($cmd | wc -l)
6588
6589         [ $nums -eq $expected ] ||
6590                 error "'$cmd' wrong: found $nums, expected $expected"
6591
6592         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6593
6594         if (( rpcs_before + glimpses != rpcs_after )); then
6595                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6596                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6597
6598                 if [[ $glimpses == 0 ]]; then
6599                         error "'$cmd' should not send glimpse RPCs to OST"
6600                 else
6601                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6602                 fi
6603         fi
6604 }
6605
6606 test_56ra() {
6607         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6608                 skip "MDS < 2.12.58 doesn't return LSOM data"
6609         local dir=$DIR/$tdir
6610         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6611
6612         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6613
6614         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6615         $LCTL set_param -n llite.*.statahead_agl=0
6616         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6617
6618         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6619         # open and close all files to ensure LSOM is updated
6620         cancel_lru_locks $OSC
6621         find $dir -type f | xargs cat > /dev/null
6622
6623         #   expect_found  glimpse_rpcs  command_to_run
6624         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6625         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6626         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6627         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6628
6629         echo "test" > $dir/$tfile
6630         echo "test2" > $dir/$tfile.2 && sync
6631         cancel_lru_locks $OSC
6632         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6633
6634         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6635         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6636         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6637         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6638
6639         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6640         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6641         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6642         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6643         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6644         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6645 }
6646 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6647
6648 test_56rb() {
6649         local dir=$DIR/$tdir
6650         local tmp=$TMP/$tfile.log
6651         local mdt_idx;
6652
6653         test_mkdir -p $dir || error "failed to mkdir $dir"
6654         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6655                 error "failed to setstripe $dir/$tfile"
6656         mdt_idx=$($LFS getdirstripe -i $dir)
6657         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6658
6659         stack_trap "rm -f $tmp" EXIT
6660         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6661         ! grep -q obd_uuid $tmp ||
6662                 error "failed to find --size +100K --ost 0 $dir"
6663         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6664         ! grep -q obd_uuid $tmp ||
6665                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6666 }
6667 run_test 56rb "check lfs find --size --ost/--mdt works"
6668
6669 test_56rc() {
6670         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6671         local dir=$DIR/$tdir
6672         local found
6673
6674         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6675         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6676         (( $MDSCOUNT > 2 )) &&
6677                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6678         mkdir $dir/$tdir-{1..10}
6679         touch $dir/$tfile-{1..10}
6680
6681         found=$($LFS find $dir --mdt-count 2 | wc -l)
6682         expect=11
6683         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6684
6685         found=$($LFS find $dir -T +1 | wc -l)
6686         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6687         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6688
6689         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6690         expect=11
6691         (( $found == $expect )) || error "found $found all_char, expect $expect"
6692
6693         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6694         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6695         (( $found == $expect )) || error "found $found all_char, expect $expect"
6696 }
6697 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6698
6699 test_56s() { # LU-611 #LU-9369
6700         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6701
6702         local dir=$DIR/$tdir
6703         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6704
6705         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6706         for i in $(seq $NUMDIRS); do
6707                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6708         done
6709
6710         local expected=$NUMDIRS
6711         local cmd="$LFS find -c $OSTCOUNT $dir"
6712         local nums=$($cmd | wc -l)
6713
6714         [ $nums -eq $expected ] || {
6715                 $LFS getstripe -R $dir
6716                 error "'$cmd' wrong: found $nums, expected $expected"
6717         }
6718
6719         expected=$((NUMDIRS + onestripe))
6720         cmd="$LFS find -stripe-count +0 -type f $dir"
6721         nums=$($cmd | wc -l)
6722         [ $nums -eq $expected ] || {
6723                 $LFS getstripe -R $dir
6724                 error "'$cmd' wrong: found $nums, expected $expected"
6725         }
6726
6727         expected=$onestripe
6728         cmd="$LFS find -stripe-count 1 -type f $dir"
6729         nums=$($cmd | wc -l)
6730         [ $nums -eq $expected ] || {
6731                 $LFS getstripe -R $dir
6732                 error "'$cmd' wrong: found $nums, expected $expected"
6733         }
6734
6735         cmd="$LFS find -stripe-count -2 -type f $dir"
6736         nums=$($cmd | wc -l)
6737         [ $nums -eq $expected ] || {
6738                 $LFS getstripe -R $dir
6739                 error "'$cmd' wrong: found $nums, expected $expected"
6740         }
6741
6742         expected=0
6743         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] || {
6746                 $LFS getstripe -R $dir
6747                 error "'$cmd' wrong: found $nums, expected $expected"
6748         }
6749 }
6750 run_test 56s "check lfs find -stripe-count works"
6751
6752 test_56t() { # LU-611 #LU-9369
6753         local dir=$DIR/$tdir
6754
6755         setup_56 $dir 0 $NUMDIRS
6756         for i in $(seq $NUMDIRS); do
6757                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6758         done
6759
6760         local expected=$NUMDIRS
6761         local cmd="$LFS find -S 8M $dir"
6762         local nums=$($cmd | wc -l)
6763
6764         [ $nums -eq $expected ] || {
6765                 $LFS getstripe -R $dir
6766                 error "'$cmd' wrong: found $nums, expected $expected"
6767         }
6768         rm -rf $dir
6769
6770         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6771
6772         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6773
6774         expected=$(((NUMDIRS + 1) * NUMFILES))
6775         cmd="$LFS find -stripe-size 512k -type f $dir"
6776         nums=$($cmd | wc -l)
6777         [ $nums -eq $expected ] ||
6778                 error "'$cmd' wrong: found $nums, expected $expected"
6779
6780         cmd="$LFS find -stripe-size +320k -type f $dir"
6781         nums=$($cmd | wc -l)
6782         [ $nums -eq $expected ] ||
6783                 error "'$cmd' wrong: found $nums, expected $expected"
6784
6785         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6786         cmd="$LFS find -stripe-size +200k -type f $dir"
6787         nums=$($cmd | wc -l)
6788         [ $nums -eq $expected ] ||
6789                 error "'$cmd' wrong: found $nums, expected $expected"
6790
6791         cmd="$LFS find -stripe-size -640k -type f $dir"
6792         nums=$($cmd | wc -l)
6793         [ $nums -eq $expected ] ||
6794                 error "'$cmd' wrong: found $nums, expected $expected"
6795
6796         expected=4
6797         cmd="$LFS find -stripe-size 256k -type f $dir"
6798         nums=$($cmd | wc -l)
6799         [ $nums -eq $expected ] ||
6800                 error "'$cmd' wrong: found $nums, expected $expected"
6801
6802         cmd="$LFS find -stripe-size -320k -type f $dir"
6803         nums=$($cmd | wc -l)
6804         [ $nums -eq $expected ] ||
6805                 error "'$cmd' wrong: found $nums, expected $expected"
6806
6807         expected=0
6808         cmd="$LFS find -stripe-size 1024k -type f $dir"
6809         nums=$($cmd | wc -l)
6810         [ $nums -eq $expected ] ||
6811                 error "'$cmd' wrong: found $nums, expected $expected"
6812 }
6813 run_test 56t "check lfs find -stripe-size works"
6814
6815 test_56u() { # LU-611
6816         local dir=$DIR/$tdir
6817
6818         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6819
6820         if [[ $OSTCOUNT -gt 1 ]]; then
6821                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6822                 onestripe=4
6823         else
6824                 onestripe=0
6825         fi
6826
6827         local expected=$(((NUMDIRS + 1) * NUMFILES))
6828         local cmd="$LFS find -stripe-index 0 -type f $dir"
6829         local nums=$($cmd | wc -l)
6830
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833
6834         expected=$onestripe
6835         cmd="$LFS find -stripe-index 1 -type f $dir"
6836         nums=$($cmd | wc -l)
6837         [ $nums -eq $expected ] ||
6838                 error "'$cmd' wrong: found $nums, expected $expected"
6839
6840         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6841         nums=$($cmd | wc -l)
6842         [ $nums -eq $expected ] ||
6843                 error "'$cmd' wrong: found $nums, expected $expected"
6844
6845         expected=0
6846         # This should produce an error and not return any files
6847         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6848         nums=$($cmd 2>/dev/null | wc -l)
6849         [ $nums -eq $expected ] ||
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851
6852         if [[ $OSTCOUNT -gt 1 ]]; then
6853                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6854                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6855                 nums=$($cmd | wc -l)
6856                 [ $nums -eq $expected ] ||
6857                         error "'$cmd' wrong: found $nums, expected $expected"
6858         fi
6859 }
6860 run_test 56u "check lfs find -stripe-index works"
6861
6862 test_56v() {
6863         local mdt_idx=0
6864         local dir=$DIR/$tdir
6865
6866         setup_56 $dir $NUMFILES $NUMDIRS
6867
6868         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6869         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6870
6871         for file in $($LFS find -m $UUID $dir); do
6872                 file_midx=$($LFS getstripe -m $file)
6873                 [ $file_midx -eq $mdt_idx ] ||
6874                         error "lfs find -m $UUID != getstripe -m $file_midx"
6875         done
6876 }
6877 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6878
6879 test_56w() {
6880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6882
6883         local dir=$DIR/$tdir
6884
6885         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6886
6887         local stripe_size=$($LFS getstripe -S -d $dir) ||
6888                 error "$LFS getstripe -S -d $dir failed"
6889         stripe_size=${stripe_size%% *}
6890
6891         local file_size=$((stripe_size * OSTCOUNT))
6892         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6893         local required_space=$((file_num * file_size))
6894         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6895                            head -n1)
6896         [[ $free_space -le $((required_space / 1024)) ]] &&
6897                 skip_env "need $required_space, have $free_space kbytes"
6898
6899         local dd_bs=65536
6900         local dd_count=$((file_size / dd_bs))
6901
6902         # write data into the files
6903         local i
6904         local j
6905         local file
6906
6907         for i in $(seq $NUMFILES); do
6908                 file=$dir/file$i
6909                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6910                         error "write data into $file failed"
6911         done
6912         for i in $(seq $NUMDIRS); do
6913                 for j in $(seq $NUMFILES); do
6914                         file=$dir/dir$i/file$j
6915                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6916                                 error "write data into $file failed"
6917                 done
6918         done
6919
6920         # $LFS_MIGRATE will fail if hard link migration is unsupported
6921         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6922                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6923                         error "creating links to $dir/dir1/file1 failed"
6924         fi
6925
6926         local expected=-1
6927
6928         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6929
6930         # lfs_migrate file
6931         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6932
6933         echo "$cmd"
6934         eval $cmd || error "$cmd failed"
6935
6936         check_stripe_count $dir/file1 $expected
6937
6938         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6939         then
6940                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6941                 # OST 1 if it is on OST 0. This file is small enough to
6942                 # be on only one stripe.
6943                 file=$dir/migr_1_ost
6944                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6945                         error "write data into $file failed"
6946                 local obdidx=$($LFS getstripe -i $file)
6947                 local oldmd5=$(md5sum $file)
6948                 local newobdidx=0
6949
6950                 [[ $obdidx -eq 0 ]] && newobdidx=1
6951                 cmd="$LFS migrate -i $newobdidx $file"
6952                 echo $cmd
6953                 eval $cmd || error "$cmd failed"
6954
6955                 local realobdix=$($LFS getstripe -i $file)
6956                 local newmd5=$(md5sum $file)
6957
6958                 [[ $newobdidx -ne $realobdix ]] &&
6959                         error "new OST is different (was=$obdidx, "\
6960                               "wanted=$newobdidx, got=$realobdix)"
6961                 [[ "$oldmd5" != "$newmd5" ]] &&
6962                         error "md5sum differ: $oldmd5, $newmd5"
6963         fi
6964
6965         # lfs_migrate dir
6966         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6967         echo "$cmd"
6968         eval $cmd || error "$cmd failed"
6969
6970         for j in $(seq $NUMFILES); do
6971                 check_stripe_count $dir/dir1/file$j $expected
6972         done
6973
6974         # lfs_migrate works with lfs find
6975         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6976              $LFS_MIGRATE -y -c $expected"
6977         echo "$cmd"
6978         eval $cmd || error "$cmd failed"
6979
6980         for i in $(seq 2 $NUMFILES); do
6981                 check_stripe_count $dir/file$i $expected
6982         done
6983         for i in $(seq 2 $NUMDIRS); do
6984                 for j in $(seq $NUMFILES); do
6985                 check_stripe_count $dir/dir$i/file$j $expected
6986                 done
6987         done
6988 }
6989 run_test 56w "check lfs_migrate -c stripe_count works"
6990
6991 test_56wb() {
6992         local file1=$DIR/$tdir/file1
6993         local create_pool=false
6994         local initial_pool=$($LFS getstripe -p $DIR)
6995         local pool_list=()
6996         local pool=""
6997
6998         echo -n "Creating test dir..."
6999         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7000         echo "done."
7001
7002         echo -n "Creating test file..."
7003         touch $file1 || error "cannot create file"
7004         echo "done."
7005
7006         echo -n "Detecting existing pools..."
7007         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7008
7009         if [ ${#pool_list[@]} -gt 0 ]; then
7010                 echo "${pool_list[@]}"
7011                 for thispool in "${pool_list[@]}"; do
7012                         if [[ -z "$initial_pool" ||
7013                               "$initial_pool" != "$thispool" ]]; then
7014                                 pool="$thispool"
7015                                 echo "Using existing pool '$pool'"
7016                                 break
7017                         fi
7018                 done
7019         else
7020                 echo "none detected."
7021         fi
7022         if [ -z "$pool" ]; then
7023                 pool=${POOL:-testpool}
7024                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7025                 echo -n "Creating pool '$pool'..."
7026                 create_pool=true
7027                 pool_add $pool &> /dev/null ||
7028                         error "pool_add failed"
7029                 echo "done."
7030
7031                 echo -n "Adding target to pool..."
7032                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7033                         error "pool_add_targets failed"
7034                 echo "done."
7035         fi
7036
7037         echo -n "Setting pool using -p option..."
7038         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7039                 error "migrate failed rc = $?"
7040         echo "done."
7041
7042         echo -n "Verifying test file is in pool after migrating..."
7043         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7044                 error "file was not migrated to pool $pool"
7045         echo "done."
7046
7047         echo -n "Removing test file from pool '$pool'..."
7048         # "lfs migrate $file" won't remove the file from the pool
7049         # until some striping information is changed.
7050         $LFS migrate -c 1 $file1 &> /dev/null ||
7051                 error "cannot remove from pool"
7052         [ "$($LFS getstripe -p $file1)" ] &&
7053                 error "pool still set"
7054         echo "done."
7055
7056         echo -n "Setting pool using --pool option..."
7057         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7058                 error "migrate failed rc = $?"
7059         echo "done."
7060
7061         # Clean up
7062         rm -f $file1
7063         if $create_pool; then
7064                 destroy_test_pools 2> /dev/null ||
7065                         error "destroy test pools failed"
7066         fi
7067 }
7068 run_test 56wb "check lfs_migrate pool support"
7069
7070 test_56wc() {
7071         local file1="$DIR/$tdir/file1"
7072         local parent_ssize
7073         local parent_scount
7074         local cur_ssize
7075         local cur_scount
7076         local orig_ssize
7077
7078         echo -n "Creating test dir..."
7079         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7080         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7081                 error "cannot set stripe by '-S 1M -c 1'"
7082         echo "done"
7083
7084         echo -n "Setting initial stripe for test file..."
7085         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7086                 error "cannot set stripe"
7087         cur_ssize=$($LFS getstripe -S "$file1")
7088         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7089         echo "done."
7090
7091         # File currently set to -S 512K -c 1
7092
7093         # Ensure -c and -S options are rejected when -R is set
7094         echo -n "Verifying incompatible options are detected..."
7095         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7096                 error "incompatible -c and -R options not detected"
7097         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7098                 error "incompatible -S and -R options not detected"
7099         echo "done."
7100
7101         # Ensure unrecognized options are passed through to 'lfs migrate'
7102         echo -n "Verifying -S option is passed through to lfs migrate..."
7103         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7104                 error "migration failed"
7105         cur_ssize=$($LFS getstripe -S "$file1")
7106         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7107         echo "done."
7108
7109         # File currently set to -S 1M -c 1
7110
7111         # Ensure long options are supported
7112         echo -n "Verifying long options supported..."
7113         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7114                 error "long option without argument not supported"
7115         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7116                 error "long option with argument not supported"
7117         cur_ssize=$($LFS getstripe -S "$file1")
7118         [ $cur_ssize -eq 524288 ] ||
7119                 error "migrate --stripe-size $cur_ssize != 524288"
7120         echo "done."
7121
7122         # File currently set to -S 512K -c 1
7123
7124         if [ "$OSTCOUNT" -gt 1 ]; then
7125                 echo -n "Verifying explicit stripe count can be set..."
7126                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7127                         error "migrate failed"
7128                 cur_scount=$($LFS getstripe -c "$file1")
7129                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7130                 echo "done."
7131         fi
7132
7133         # File currently set to -S 512K -c 1 or -S 512K -c 2
7134
7135         # Ensure parent striping is used if -R is set, and no stripe
7136         # count or size is specified
7137         echo -n "Setting stripe for parent directory..."
7138         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7139                 error "cannot set stripe '-S 2M -c 1'"
7140         echo "done."
7141
7142         echo -n "Verifying restripe option uses parent stripe settings..."
7143         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7144         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7145         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7146                 error "migrate failed"
7147         cur_ssize=$($LFS getstripe -S "$file1")
7148         [ $cur_ssize -eq $parent_ssize ] ||
7149                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7150         cur_scount=$($LFS getstripe -c "$file1")
7151         [ $cur_scount -eq $parent_scount ] ||
7152                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7153         echo "done."
7154
7155         # File currently set to -S 1M -c 1
7156
7157         # Ensure striping is preserved if -R is not set, and no stripe
7158         # count or size is specified
7159         echo -n "Verifying striping size preserved when not specified..."
7160         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7161         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7162                 error "cannot set stripe on parent directory"
7163         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7164                 error "migrate failed"
7165         cur_ssize=$($LFS getstripe -S "$file1")
7166         [ $cur_ssize -eq $orig_ssize ] ||
7167                 error "migrate by default $cur_ssize != $orig_ssize"
7168         echo "done."
7169
7170         # Ensure file name properly detected when final option has no argument
7171         echo -n "Verifying file name properly detected..."
7172         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7173                 error "file name interpreted as option argument"
7174         echo "done."
7175
7176         # Clean up
7177         rm -f "$file1"
7178 }
7179 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7180
7181 test_56wd() {
7182         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7183
7184         local file1=$DIR/$tdir/file1
7185
7186         echo -n "Creating test dir..."
7187         test_mkdir $DIR/$tdir || error "cannot create dir"
7188         echo "done."
7189
7190         echo -n "Creating test file..."
7191         touch $file1
7192         echo "done."
7193
7194         # Ensure 'lfs migrate' will fail by using a non-existent option,
7195         # and make sure rsync is not called to recover
7196         echo -n "Make sure --no-rsync option works..."
7197         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7198                 grep -q 'refusing to fall back to rsync' ||
7199                 error "rsync was called with --no-rsync set"
7200         echo "done."
7201
7202         # Ensure rsync is called without trying 'lfs migrate' first
7203         echo -n "Make sure --rsync option works..."
7204         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7205                 grep -q 'falling back to rsync' &&
7206                 error "lfs migrate was called with --rsync set"
7207         echo "done."
7208
7209         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7210         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7211                 grep -q 'at the same time' ||
7212                 error "--rsync and --no-rsync accepted concurrently"
7213         echo "done."
7214
7215         # Clean up
7216         rm -f $file1
7217 }
7218 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7219
7220 test_56we() {
7221         local td=$DIR/$tdir
7222         local tf=$td/$tfile
7223
7224         test_mkdir $td || error "cannot create $td"
7225         touch $tf || error "cannot touch $tf"
7226
7227         echo -n "Make sure --non-direct|-D works..."
7228         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7229                 grep -q "lfs migrate --non-direct" ||
7230                 error "--non-direct option cannot work correctly"
7231         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7232                 grep -q "lfs migrate -D" ||
7233                 error "-D option cannot work correctly"
7234         echo "done."
7235 }
7236 run_test 56we "check lfs_migrate --non-direct|-D support"
7237
7238 test_56x() {
7239         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7240         check_swap_layouts_support
7241
7242         local dir=$DIR/$tdir
7243         local ref1=/etc/passwd
7244         local file1=$dir/file1
7245
7246         test_mkdir $dir || error "creating dir $dir"
7247         $LFS setstripe -c 2 $file1
7248         cp $ref1 $file1
7249         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7250         stripe=$($LFS getstripe -c $file1)
7251         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7252         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7253
7254         # clean up
7255         rm -f $file1
7256 }
7257 run_test 56x "lfs migration support"
7258
7259 test_56xa() {
7260         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7261         check_swap_layouts_support
7262
7263         local dir=$DIR/$tdir/$testnum
7264
7265         test_mkdir -p $dir
7266
7267         local ref1=/etc/passwd
7268         local file1=$dir/file1
7269
7270         $LFS setstripe -c 2 $file1
7271         cp $ref1 $file1
7272         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7273
7274         local stripe=$($LFS getstripe -c $file1)
7275
7276         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7277         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7278
7279         # clean up
7280         rm -f $file1
7281 }
7282 run_test 56xa "lfs migration --block support"
7283
7284 check_migrate_links() {
7285         local dir="$1"
7286         local file1="$dir/file1"
7287         local begin="$2"
7288         local count="$3"
7289         local runas="$4"
7290         local total_count=$(($begin + $count - 1))
7291         local symlink_count=10
7292         local uniq_count=10
7293
7294         if [ ! -f "$file1" ]; then
7295                 echo -n "creating initial file..."
7296                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7297                         error "cannot setstripe initial file"
7298                 echo "done"
7299
7300                 echo -n "creating symlinks..."
7301                 for s in $(seq 1 $symlink_count); do
7302                         ln -s "$file1" "$dir/slink$s" ||
7303                                 error "cannot create symlinks"
7304                 done
7305                 echo "done"
7306
7307                 echo -n "creating nonlinked files..."
7308                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7309                         error "cannot create nonlinked files"
7310                 echo "done"
7311         fi
7312
7313         # create hard links
7314         if [ ! -f "$dir/file$total_count" ]; then
7315                 echo -n "creating hard links $begin:$total_count..."
7316                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7317                         /dev/null || error "cannot create hard links"
7318                 echo "done"
7319         fi
7320
7321         echo -n "checking number of hard links listed in xattrs..."
7322         local fid=$($LFS getstripe -F "$file1")
7323         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7324
7325         echo "${#paths[*]}"
7326         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7327                         skip "hard link list has unexpected size, skipping test"
7328         fi
7329         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7330                         error "link names should exceed xattrs size"
7331         fi
7332
7333         echo -n "migrating files..."
7334         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7335         local rc=$?
7336         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7337         echo "done"
7338
7339         # make sure all links have been properly migrated
7340         echo -n "verifying files..."
7341         fid=$($LFS getstripe -F "$file1") ||
7342                 error "cannot get fid for file $file1"
7343         for i in $(seq 2 $total_count); do
7344                 local fid2=$($LFS getstripe -F $dir/file$i)
7345
7346                 [ "$fid2" == "$fid" ] ||
7347                         error "migrated hard link has mismatched FID"
7348         done
7349
7350         # make sure hard links were properly detected, and migration was
7351         # performed only once for the entire link set; nonlinked files should
7352         # also be migrated
7353         local actual=$(grep -c 'done' <<< "$migrate_out")
7354         local expected=$(($uniq_count + 1))
7355
7356         [ "$actual" -eq  "$expected" ] ||
7357                 error "hard links individually migrated ($actual != $expected)"
7358
7359         # make sure the correct number of hard links are present
7360         local hardlinks=$(stat -c '%h' "$file1")
7361
7362         [ $hardlinks -eq $total_count ] ||
7363                 error "num hard links $hardlinks != $total_count"
7364         echo "done"
7365
7366         return 0
7367 }
7368
7369 test_56xb() {
7370         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7371                 skip "Need MDS version at least 2.10.55"
7372
7373         local dir="$DIR/$tdir"
7374
7375         test_mkdir "$dir" || error "cannot create dir $dir"
7376
7377         echo "testing lfs migrate mode when all links fit within xattrs"
7378         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7379
7380         echo "testing rsync mode when all links fit within xattrs"
7381         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7382
7383         echo "testing lfs migrate mode when all links do not fit within xattrs"
7384         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7385
7386         echo "testing rsync mode when all links do not fit within xattrs"
7387         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7388
7389         chown -R $RUNAS_ID $dir
7390         echo "testing non-root lfs migrate mode when not all links are in xattr"
7391         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7392
7393         # clean up
7394         rm -rf $dir
7395 }
7396 run_test 56xb "lfs migration hard link support"
7397
7398 test_56xc() {
7399         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7400
7401         local dir="$DIR/$tdir"
7402
7403         test_mkdir "$dir" || error "cannot create dir $dir"
7404
7405         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7406         echo -n "Setting initial stripe for 20MB test file..."
7407         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7408                 error "cannot setstripe 20MB file"
7409         echo "done"
7410         echo -n "Sizing 20MB test file..."
7411         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7412         echo "done"
7413         echo -n "Verifying small file autostripe count is 1..."
7414         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7415                 error "cannot migrate 20MB file"
7416         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7417                 error "cannot get stripe for $dir/20mb"
7418         [ $stripe_count -eq 1 ] ||
7419                 error "unexpected stripe count $stripe_count for 20MB file"
7420         rm -f "$dir/20mb"
7421         echo "done"
7422
7423         # Test 2: File is small enough to fit within the available space on
7424         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7425         # have at least an additional 1KB for each desired stripe for test 3
7426         echo -n "Setting stripe for 1GB test file..."
7427         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7428         echo "done"
7429         echo -n "Sizing 1GB test file..."
7430         # File size is 1GB + 3KB
7431         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7432         echo "done"
7433
7434         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7435         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7436         if (( avail > 524288 * OSTCOUNT )); then
7437                 echo -n "Migrating 1GB file..."
7438                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7439                         error "cannot migrate 1GB file"
7440                 echo "done"
7441                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7442                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7443                         error "cannot getstripe for 1GB file"
7444                 [ $stripe_count -eq 2 ] ||
7445                         error "unexpected stripe count $stripe_count != 2"
7446                 echo "done"
7447         fi
7448
7449         # Test 3: File is too large to fit within the available space on
7450         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7451         if [ $OSTCOUNT -ge 3 ]; then
7452                 # The required available space is calculated as
7453                 # file size (1GB + 3KB) / OST count (3).
7454                 local kb_per_ost=349526
7455
7456                 echo -n "Migrating 1GB file with limit..."
7457                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7458                         error "cannot migrate 1GB file with limit"
7459                 echo "done"
7460
7461                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7462                 echo -n "Verifying 1GB autostripe count with limited space..."
7463                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7464                         error "unexpected stripe count $stripe_count (min 3)"
7465                 echo "done"
7466         fi
7467
7468         # clean up
7469         rm -rf $dir
7470 }
7471 run_test 56xc "lfs migration autostripe"
7472
7473 test_56xd() {
7474         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7475
7476         local dir=$DIR/$tdir
7477         local f_mgrt=$dir/$tfile.mgrt
7478         local f_yaml=$dir/$tfile.yaml
7479         local f_copy=$dir/$tfile.copy
7480         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7481         local layout_copy="-c 2 -S 2M -i 1"
7482         local yamlfile=$dir/yamlfile
7483         local layout_before;
7484         local layout_after;
7485
7486         test_mkdir "$dir" || error "cannot create dir $dir"
7487         $LFS setstripe $layout_yaml $f_yaml ||
7488                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7489         $LFS getstripe --yaml $f_yaml > $yamlfile
7490         $LFS setstripe $layout_copy $f_copy ||
7491                 error "cannot setstripe $f_copy with layout $layout_copy"
7492         touch $f_mgrt
7493         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7494
7495         # 1. test option --yaml
7496         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7497                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7498         layout_before=$(get_layout_param $f_yaml)
7499         layout_after=$(get_layout_param $f_mgrt)
7500         [ "$layout_after" == "$layout_before" ] ||
7501                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7502
7503         # 2. test option --copy
7504         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7505                 error "cannot migrate $f_mgrt with --copy $f_copy"
7506         layout_before=$(get_layout_param $f_copy)
7507         layout_after=$(get_layout_param $f_mgrt)
7508         [ "$layout_after" == "$layout_before" ] ||
7509                 error "lfs_migrate --copy: $layout_after != $layout_before"
7510 }
7511 run_test 56xd "check lfs_migrate --yaml and --copy support"
7512
7513 test_56xe() {
7514         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7515
7516         local dir=$DIR/$tdir
7517         local f_comp=$dir/$tfile
7518         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7519         local layout_before=""
7520         local layout_after=""
7521
7522         test_mkdir "$dir" || error "cannot create dir $dir"
7523         $LFS setstripe $layout $f_comp ||
7524                 error "cannot setstripe $f_comp with layout $layout"
7525         layout_before=$(get_layout_param $f_comp)
7526         dd if=/dev/zero of=$f_comp bs=1M count=4
7527
7528         # 1. migrate a comp layout file by lfs_migrate
7529         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7530         layout_after=$(get_layout_param $f_comp)
7531         [ "$layout_before" == "$layout_after" ] ||
7532                 error "lfs_migrate: $layout_before != $layout_after"
7533
7534         # 2. migrate a comp layout file by lfs migrate
7535         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7536         layout_after=$(get_layout_param $f_comp)
7537         [ "$layout_before" == "$layout_after" ] ||
7538                 error "lfs migrate: $layout_before != $layout_after"
7539 }
7540 run_test 56xe "migrate a composite layout file"
7541
7542 test_56xf() {
7543         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7544
7545         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7546                 skip "Need server version at least 2.13.53"
7547
7548         local dir=$DIR/$tdir
7549         local f_comp=$dir/$tfile
7550         local layout="-E 1M -c1 -E -1 -c2"
7551         local fid_before=""
7552         local fid_after=""
7553
7554         test_mkdir "$dir" || error "cannot create dir $dir"
7555         $LFS setstripe $layout $f_comp ||
7556                 error "cannot setstripe $f_comp with layout $layout"
7557         fid_before=$($LFS getstripe --fid $f_comp)
7558         dd if=/dev/zero of=$f_comp bs=1M count=4
7559
7560         # 1. migrate a comp layout file to a comp layout
7561         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7562         fid_after=$($LFS getstripe --fid $f_comp)
7563         [ "$fid_before" == "$fid_after" ] ||
7564                 error "comp-to-comp migrate: $fid_before != $fid_after"
7565
7566         # 2. migrate a comp layout file to a plain layout
7567         $LFS migrate -c2 $f_comp ||
7568                 error "cannot migrate $f_comp by lfs migrate"
7569         fid_after=$($LFS getstripe --fid $f_comp)
7570         [ "$fid_before" == "$fid_after" ] ||
7571                 error "comp-to-plain migrate: $fid_before != $fid_after"
7572
7573         # 3. migrate a plain layout file to a comp layout
7574         $LFS migrate $layout $f_comp ||
7575                 error "cannot migrate $f_comp by lfs migrate"
7576         fid_after=$($LFS getstripe --fid $f_comp)
7577         [ "$fid_before" == "$fid_after" ] ||
7578                 error "plain-to-comp migrate: $fid_before != $fid_after"
7579 }
7580 run_test 56xf "FID is not lost during migration of a composite layout file"
7581
7582 test_56y() {
7583         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7584                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7585
7586         local res=""
7587         local dir=$DIR/$tdir
7588         local f1=$dir/file1
7589         local f2=$dir/file2
7590
7591         test_mkdir -p $dir || error "creating dir $dir"
7592         touch $f1 || error "creating std file $f1"
7593         $MULTIOP $f2 H2c || error "creating released file $f2"
7594
7595         # a directory can be raid0, so ask only for files
7596         res=$($LFS find $dir -L raid0 -type f | wc -l)
7597         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7598
7599         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7600         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7601
7602         # only files can be released, so no need to force file search
7603         res=$($LFS find $dir -L released)
7604         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7605
7606         res=$($LFS find $dir -type f \! -L released)
7607         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7608 }
7609 run_test 56y "lfs find -L raid0|released"
7610
7611 test_56z() { # LU-4824
7612         # This checks to make sure 'lfs find' continues after errors
7613         # There are two classes of errors that should be caught:
7614         # - If multiple paths are provided, all should be searched even if one
7615         #   errors out
7616         # - If errors are encountered during the search, it should not terminate
7617         #   early
7618         local dir=$DIR/$tdir
7619         local i
7620
7621         test_mkdir $dir
7622         for i in d{0..9}; do
7623                 test_mkdir $dir/$i
7624                 touch $dir/$i/$tfile
7625         done
7626         $LFS find $DIR/non_existent_dir $dir &&
7627                 error "$LFS find did not return an error"
7628         # Make a directory unsearchable. This should NOT be the last entry in
7629         # directory order.  Arbitrarily pick the 6th entry
7630         chmod 700 $($LFS find $dir -type d | sed '6!d')
7631
7632         $RUNAS $LFS find $DIR/non_existent $dir
7633         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7634
7635         # The user should be able to see 10 directories and 9 files
7636         (( count == 19 )) ||
7637                 error "$LFS find found $count != 19 entries after error"
7638 }
7639 run_test 56z "lfs find should continue after an error"
7640
7641 test_56aa() { # LU-5937
7642         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7643
7644         local dir=$DIR/$tdir
7645
7646         mkdir $dir
7647         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7648
7649         createmany -o $dir/striped_dir/${tfile}- 1024
7650         local dirs=$($LFS find --size +8k $dir/)
7651
7652         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7653 }
7654 run_test 56aa "lfs find --size under striped dir"
7655
7656 test_56ab() { # LU-10705
7657         test_mkdir $DIR/$tdir
7658         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7659         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7660         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7661         # Flush writes to ensure valid blocks.  Need to be more thorough for
7662         # ZFS, since blocks are not allocated/returned to client immediately.
7663         sync_all_data
7664         wait_zfs_commit ost1 2
7665         cancel_lru_locks osc
7666         ls -ls $DIR/$tdir
7667
7668         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7669
7670         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7671
7672         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7673         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7674
7675         rm -f $DIR/$tdir/$tfile.[123]
7676 }
7677 run_test 56ab "lfs find --blocks"
7678
7679 # LU-11188
7680 test_56aca() {
7681         local dir="$DIR/$tdir"
7682         local perms=(001 002 003 004 005 006 007
7683                      010 020 030 040 050 060 070
7684                      100 200 300 400 500 600 700
7685                      111 222 333 444 555 666 777)
7686         local perm_minus=(8 8 4 8 4 4 2
7687                           8 8 4 8 4 4 2
7688                           8 8 4 8 4 4 2
7689                           4 4 2 4 2 2 1)
7690         local perm_slash=(8  8 12  8 12 12 14
7691                           8  8 12  8 12 12 14
7692                           8  8 12  8 12 12 14
7693                          16 16 24 16 24 24 28)
7694
7695         test_mkdir "$dir"
7696         for perm in ${perms[*]}; do
7697                 touch "$dir/$tfile.$perm"
7698                 chmod $perm "$dir/$tfile.$perm"
7699         done
7700
7701         for ((i = 0; i < ${#perms[*]}; i++)); do
7702                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7703                 (( $num == 1 )) ||
7704                         error "lfs find -perm ${perms[i]}:"\
7705                               "$num != 1"
7706
7707                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7708                 (( $num == ${perm_minus[i]} )) ||
7709                         error "lfs find -perm -${perms[i]}:"\
7710                               "$num != ${perm_minus[i]}"
7711
7712                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7713                 (( $num == ${perm_slash[i]} )) ||
7714                         error "lfs find -perm /${perms[i]}:"\
7715                               "$num != ${perm_slash[i]}"
7716         done
7717 }
7718 run_test 56aca "check lfs find -perm with octal representation"
7719
7720 test_56acb() {
7721         local dir=$DIR/$tdir
7722         # p is the permission of write and execute for user, group and other
7723         # without the umask. It is used to test +wx.
7724         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7725         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7726         local symbolic=(+t  a+t u+t g+t o+t
7727                         g+s u+s o+s +s o+sr
7728                         o=r,ug+o,u+w
7729                         u+ g+ o+ a+ ugo+
7730                         u- g- o- a- ugo-
7731                         u= g= o= a= ugo=
7732                         o=r,ug+o,u+w u=r,a+u,u+w
7733                         g=r,ugo=g,u+w u+x,+X +X
7734                         u+x,u+X u+X u+x,g+X o+r,+X
7735                         u+x,go+X +wx +rwx)
7736
7737         test_mkdir $dir
7738         for perm in ${perms[*]}; do
7739                 touch "$dir/$tfile.$perm"
7740                 chmod $perm "$dir/$tfile.$perm"
7741         done
7742
7743         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7744                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7745
7746                 (( $num == 1 )) ||
7747                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7748         done
7749 }
7750 run_test 56acb "check lfs find -perm with symbolic representation"
7751
7752 test_56acc() {
7753         local dir=$DIR/$tdir
7754         local tests="17777 787 789 abcd
7755                 ug=uu ug=a ug=gu uo=ou urw
7756                 u+xg+x a=r,u+x,"
7757
7758         test_mkdir $dir
7759         for err in $tests; do
7760                 if $LFS find $dir -perm $err 2>/dev/null; then
7761                         error "lfs find -perm $err: parsing should have failed"
7762                 fi
7763         done
7764 }
7765 run_test 56acc "check parsing error for lfs find -perm"
7766
7767 test_56ba() {
7768         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7769                 skip "Need MDS version at least 2.10.50"
7770
7771         # Create composite files with one component
7772         local dir=$DIR/$tdir
7773
7774         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7775         # Create composite files with three components
7776         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7777         # Create non-composite files
7778         createmany -o $dir/${tfile}- 10
7779
7780         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7781
7782         [[ $nfiles == 10 ]] ||
7783                 error "lfs find -E 1M found $nfiles != 10 files"
7784
7785         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7786         [[ $nfiles == 25 ]] ||
7787                 error "lfs find ! -E 1M found $nfiles != 25 files"
7788
7789         # All files have a component that starts at 0
7790         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7791         [[ $nfiles == 35 ]] ||
7792                 error "lfs find --component-start 0 - $nfiles != 35 files"
7793
7794         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7795         [[ $nfiles == 15 ]] ||
7796                 error "lfs find --component-start 2M - $nfiles != 15 files"
7797
7798         # All files created here have a componenet that does not starts at 2M
7799         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7800         [[ $nfiles == 35 ]] ||
7801                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7802
7803         # Find files with a specified number of components
7804         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7805         [[ $nfiles == 15 ]] ||
7806                 error "lfs find --component-count 3 - $nfiles != 15 files"
7807
7808         # Remember non-composite files have a component count of zero
7809         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7810         [[ $nfiles == 10 ]] ||
7811                 error "lfs find --component-count 0 - $nfiles != 10 files"
7812
7813         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7814         [[ $nfiles == 20 ]] ||
7815                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7816
7817         # All files have a flag called "init"
7818         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7819         [[ $nfiles == 35 ]] ||
7820                 error "lfs find --component-flags init - $nfiles != 35 files"
7821
7822         # Multi-component files will have a component not initialized
7823         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7824         [[ $nfiles == 15 ]] ||
7825                 error "lfs find !--component-flags init - $nfiles != 15 files"
7826
7827         rm -rf $dir
7828
7829 }
7830 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7831
7832 test_56ca() {
7833         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7834                 skip "Need MDS version at least 2.10.57"
7835
7836         local td=$DIR/$tdir
7837         local tf=$td/$tfile
7838         local dir
7839         local nfiles
7840         local cmd
7841         local i
7842         local j
7843
7844         # create mirrored directories and mirrored files
7845         mkdir $td || error "mkdir $td failed"
7846         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7847         createmany -o $tf- 10 || error "create $tf- failed"
7848
7849         for i in $(seq 2); do
7850                 dir=$td/dir$i
7851                 mkdir $dir || error "mkdir $dir failed"
7852                 $LFS mirror create -N$((3 + i)) $dir ||
7853                         error "create mirrored dir $dir failed"
7854                 createmany -o $dir/$tfile- 10 ||
7855                         error "create $dir/$tfile- failed"
7856         done
7857
7858         # change the states of some mirrored files
7859         echo foo > $tf-6
7860         for i in $(seq 2); do
7861                 dir=$td/dir$i
7862                 for j in $(seq 4 9); do
7863                         echo foo > $dir/$tfile-$j
7864                 done
7865         done
7866
7867         # find mirrored files with specific mirror count
7868         cmd="$LFS find --mirror-count 3 --type f $td"
7869         nfiles=$($cmd | wc -l)
7870         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7871
7872         cmd="$LFS find ! --mirror-count 3 --type f $td"
7873         nfiles=$($cmd | wc -l)
7874         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7875
7876         cmd="$LFS find --mirror-count +2 --type f $td"
7877         nfiles=$($cmd | wc -l)
7878         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7879
7880         cmd="$LFS find --mirror-count -6 --type f $td"
7881         nfiles=$($cmd | wc -l)
7882         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7883
7884         # find mirrored files with specific file state
7885         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7886         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7887
7888         cmd="$LFS find --mirror-state=ro --type f $td"
7889         nfiles=$($cmd | wc -l)
7890         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7891
7892         cmd="$LFS find ! --mirror-state=ro --type f $td"
7893         nfiles=$($cmd | wc -l)
7894         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7895
7896         cmd="$LFS find --mirror-state=wp --type f $td"
7897         nfiles=$($cmd | wc -l)
7898         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7899
7900         cmd="$LFS find ! --mirror-state=sp --type f $td"
7901         nfiles=$($cmd | wc -l)
7902         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7903 }
7904 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7905
7906 test_56da() { # LU-14179
7907         local path=$DIR/$tdir
7908
7909         test_mkdir $path
7910         cd $path
7911
7912         local longdir=$(str_repeat 'a' 255)
7913
7914         for i in {1..15}; do
7915                 path=$path/$longdir
7916                 test_mkdir $longdir
7917                 cd $longdir
7918         done
7919
7920         local len=${#path}
7921         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7922
7923         test_mkdir $lastdir
7924         cd $lastdir
7925         # PATH_MAX-1
7926         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7927
7928         # NAME_MAX
7929         touch $(str_repeat 'f' 255)
7930
7931         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7932                 error "lfs find reported an error"
7933
7934         rm -rf $DIR/$tdir
7935 }
7936 run_test 56da "test lfs find with long paths"
7937
7938 test_57a() {
7939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7940         # note test will not do anything if MDS is not local
7941         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7942                 skip_env "ldiskfs only test"
7943         fi
7944         remote_mds_nodsh && skip "remote MDS with nodsh"
7945
7946         local MNTDEV="osd*.*MDT*.mntdev"
7947         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7948         [ -z "$DEV" ] && error "can't access $MNTDEV"
7949         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7950                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7951                         error "can't access $DEV"
7952                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7953                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7954                 rm $TMP/t57a.dump
7955         done
7956 }
7957 run_test 57a "verify MDS filesystem created with large inodes =="
7958
7959 test_57b() {
7960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7961         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7962                 skip_env "ldiskfs only test"
7963         fi
7964         remote_mds_nodsh && skip "remote MDS with nodsh"
7965
7966         local dir=$DIR/$tdir
7967         local filecount=100
7968         local file1=$dir/f1
7969         local fileN=$dir/f$filecount
7970
7971         rm -rf $dir || error "removing $dir"
7972         test_mkdir -c1 $dir
7973         local mdtidx=$($LFS getstripe -m $dir)
7974         local mdtname=MDT$(printf %04x $mdtidx)
7975         local facet=mds$((mdtidx + 1))
7976
7977         echo "mcreating $filecount files"
7978         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7979
7980         # verify that files do not have EAs yet
7981         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7982                 error "$file1 has an EA"
7983         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7984                 error "$fileN has an EA"
7985
7986         sync
7987         sleep 1
7988         df $dir  #make sure we get new statfs data
7989         local mdsfree=$(do_facet $facet \
7990                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7991         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7992         local file
7993
7994         echo "opening files to create objects/EAs"
7995         for file in $(seq -f $dir/f%g 1 $filecount); do
7996                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7997                         error "opening $file"
7998         done
7999
8000         # verify that files have EAs now
8001         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8002         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8003
8004         sleep 1  #make sure we get new statfs data
8005         df $dir
8006         local mdsfree2=$(do_facet $facet \
8007                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8008         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8009
8010         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8011                 if [ "$mdsfree" != "$mdsfree2" ]; then
8012                         error "MDC before $mdcfree != after $mdcfree2"
8013                 else
8014                         echo "MDC before $mdcfree != after $mdcfree2"
8015                         echo "unable to confirm if MDS has large inodes"
8016                 fi
8017         fi
8018         rm -rf $dir
8019 }
8020 run_test 57b "default LOV EAs are stored inside large inodes ==="
8021
8022 test_58() {
8023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8024         [ -z "$(which wiretest 2>/dev/null)" ] &&
8025                         skip_env "could not find wiretest"
8026
8027         wiretest
8028 }
8029 run_test 58 "verify cross-platform wire constants =============="
8030
8031 test_59() {
8032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8033
8034         echo "touch 130 files"
8035         createmany -o $DIR/f59- 130
8036         echo "rm 130 files"
8037         unlinkmany $DIR/f59- 130
8038         sync
8039         # wait for commitment of removal
8040         wait_delete_completed
8041 }
8042 run_test 59 "verify cancellation of llog records async ========="
8043
8044 TEST60_HEAD="test_60 run $RANDOM"
8045 test_60a() {
8046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8047         remote_mgs_nodsh && skip "remote MGS with nodsh"
8048         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8049                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8050                         skip_env "missing subtest run-llog.sh"
8051
8052         log "$TEST60_HEAD - from kernel mode"
8053         do_facet mgs "$LCTL dk > /dev/null"
8054         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8055         do_facet mgs $LCTL dk > $TMP/$tfile
8056
8057         # LU-6388: test llog_reader
8058         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8059         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8060         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8061                         skip_env "missing llog_reader"
8062         local fstype=$(facet_fstype mgs)
8063         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8064                 skip_env "Only for ldiskfs or zfs type mgs"
8065
8066         local mntpt=$(facet_mntpt mgs)
8067         local mgsdev=$(mgsdevname 1)
8068         local fid_list
8069         local fid
8070         local rec_list
8071         local rec
8072         local rec_type
8073         local obj_file
8074         local path
8075         local seq
8076         local oid
8077         local pass=true
8078
8079         #get fid and record list
8080         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8081                 tail -n 4))
8082         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8083                 tail -n 4))
8084         #remount mgs as ldiskfs or zfs type
8085         stop mgs || error "stop mgs failed"
8086         mount_fstype mgs || error "remount mgs failed"
8087         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8088                 fid=${fid_list[i]}
8089                 rec=${rec_list[i]}
8090                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8091                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8092                 oid=$((16#$oid))
8093
8094                 case $fstype in
8095                         ldiskfs )
8096                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8097                         zfs )
8098                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8099                 esac
8100                 echo "obj_file is $obj_file"
8101                 do_facet mgs $llog_reader $obj_file
8102
8103                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8104                         awk '{ print $3 }' | sed -e "s/^type=//g")
8105                 if [ $rec_type != $rec ]; then
8106                         echo "FAILED test_60a wrong record type $rec_type," \
8107                               "should be $rec"
8108                         pass=false
8109                         break
8110                 fi
8111
8112                 #check obj path if record type is LLOG_LOGID_MAGIC
8113                 if [ "$rec" == "1064553b" ]; then
8114                         path=$(do_facet mgs $llog_reader $obj_file |
8115                                 grep "path=" | awk '{ print $NF }' |
8116                                 sed -e "s/^path=//g")
8117                         if [ $obj_file != $mntpt/$path ]; then
8118                                 echo "FAILED test_60a wrong obj path" \
8119                                       "$montpt/$path, should be $obj_file"
8120                                 pass=false
8121                                 break
8122                         fi
8123                 fi
8124         done
8125         rm -f $TMP/$tfile
8126         #restart mgs before "error", otherwise it will block the next test
8127         stop mgs || error "stop mgs failed"
8128         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8129         $pass || error "test failed, see FAILED test_60a messages for specifics"
8130 }
8131 run_test 60a "llog_test run from kernel module and test llog_reader"
8132
8133 test_60b() { # bug 6411
8134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8135
8136         dmesg > $DIR/$tfile
8137         LLOG_COUNT=$(do_facet mgs dmesg |
8138                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8139                           /llog_[a-z]*.c:[0-9]/ {
8140                                 if (marker)
8141                                         from_marker++
8142                                 from_begin++
8143                           }
8144                           END {
8145                                 if (marker)
8146                                         print from_marker
8147                                 else
8148                                         print from_begin
8149                           }")
8150
8151         [[ $LLOG_COUNT -gt 120 ]] &&
8152                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8153 }
8154 run_test 60b "limit repeated messages from CERROR/CWARN"
8155
8156 test_60c() {
8157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8158
8159         echo "create 5000 files"
8160         createmany -o $DIR/f60c- 5000
8161 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8162         lctl set_param fail_loc=0x80000137
8163         unlinkmany $DIR/f60c- 5000
8164         lctl set_param fail_loc=0
8165 }
8166 run_test 60c "unlink file when mds full"
8167
8168 test_60d() {
8169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8170
8171         SAVEPRINTK=$(lctl get_param -n printk)
8172         # verify "lctl mark" is even working"
8173         MESSAGE="test message ID $RANDOM $$"
8174         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8175         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8176
8177         lctl set_param printk=0 || error "set lnet.printk failed"
8178         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8179         MESSAGE="new test message ID $RANDOM $$"
8180         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8181         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8182         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8183
8184         lctl set_param -n printk="$SAVEPRINTK"
8185 }
8186 run_test 60d "test printk console message masking"
8187
8188 test_60e() {
8189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8190         remote_mds_nodsh && skip "remote MDS with nodsh"
8191
8192         touch $DIR/$tfile
8193 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8194         do_facet mds1 lctl set_param fail_loc=0x15b
8195         rm $DIR/$tfile
8196 }
8197 run_test 60e "no space while new llog is being created"
8198
8199 test_60f() {
8200         local old_path=$($LCTL get_param -n debug_path)
8201
8202         stack_trap "$LCTL set_param debug_path=$old_path"
8203         stack_trap "rm -f $TMP/$tfile*"
8204         rm -f $TMP/$tfile* 2> /dev/null
8205         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8206         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8207         test_mkdir $DIR/$tdir
8208         # retry in case the open is cached and not released
8209         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8210                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8211                 sleep 0.1
8212         done
8213         ls $TMP/$tfile*
8214         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8215 }
8216 run_test 60f "change debug_path works"
8217
8218 test_60g() {
8219         local pid
8220         local i
8221
8222         test_mkdir -c $MDSCOUNT $DIR/$tdir
8223
8224         (
8225                 local index=0
8226                 while true; do
8227                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8228                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8229                                 2>/dev/null
8230                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8231                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8232                         index=$((index + 1))
8233                 done
8234         ) &
8235
8236         pid=$!
8237
8238         for i in {0..100}; do
8239                 # define OBD_FAIL_OSD_TXN_START    0x19a
8240                 local index=$((i % MDSCOUNT + 1))
8241
8242                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8243                         > /dev/null
8244                 sleep 0.01
8245         done
8246
8247         kill -9 $pid
8248
8249         for i in $(seq $MDSCOUNT); do
8250                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8251         done
8252
8253         mkdir $DIR/$tdir/new || error "mkdir failed"
8254         rmdir $DIR/$tdir/new || error "rmdir failed"
8255
8256         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8257                 -t namespace
8258         for i in $(seq $MDSCOUNT); do
8259                 wait_update_facet mds$i "$LCTL get_param -n \
8260                         mdd.$(facet_svc mds$i).lfsck_namespace |
8261                         awk '/^status/ { print \\\$2 }'" "completed"
8262         done
8263
8264         ls -R $DIR/$tdir || error "ls failed"
8265         rm -rf $DIR/$tdir || error "rmdir failed"
8266 }
8267 run_test 60g "transaction abort won't cause MDT hung"
8268
8269 test_60h() {
8270         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8271                 skip "Need MDS version at least 2.12.52"
8272         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8273
8274         local f
8275
8276         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8277         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8278         for fail_loc in 0x80000188 0x80000189; do
8279                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8280                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8281                         error "mkdir $dir-$fail_loc failed"
8282                 for i in {0..10}; do
8283                         # create may fail on missing stripe
8284                         echo $i > $DIR/$tdir-$fail_loc/$i
8285                 done
8286                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8287                         error "getdirstripe $tdir-$fail_loc failed"
8288                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8289                         error "migrate $tdir-$fail_loc failed"
8290                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8291                         error "getdirstripe $tdir-$fail_loc failed"
8292                 pushd $DIR/$tdir-$fail_loc
8293                 for f in *; do
8294                         echo $f | cmp $f - || error "$f data mismatch"
8295                 done
8296                 popd
8297                 rm -rf $DIR/$tdir-$fail_loc
8298         done
8299 }
8300 run_test 60h "striped directory with missing stripes can be accessed"
8301
8302 function t60i_load() {
8303         mkdir $DIR/$tdir
8304         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8305         $LCTL set_param fail_loc=0x131c fail_val=1
8306         for ((i=0; i<5000; i++)); do
8307                 touch $DIR/$tdir/f$i
8308         done
8309 }
8310
8311 test_60i() {
8312         changelog_register || error "changelog_register failed"
8313         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8314         changelog_users $SINGLEMDS | grep -q $cl_user ||
8315                 error "User $cl_user not found in changelog_users"
8316         changelog_chmask "ALL"
8317         t60i_load &
8318         local PID=$!
8319         for((i=0; i<100; i++)); do
8320                 changelog_dump >/dev/null ||
8321                         error "can't read changelog"
8322         done
8323         kill $PID
8324         wait $PID
8325         changelog_deregister || error "changelog_deregister failed"
8326         $LCTL set_param fail_loc=0
8327 }
8328 run_test 60i "llog: new record vs reader race"
8329
8330 test_61a() {
8331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8332
8333         f="$DIR/f61"
8334         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8335         cancel_lru_locks osc
8336         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8337         sync
8338 }
8339 run_test 61a "mmap() writes don't make sync hang ================"
8340
8341 test_61b() {
8342         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8343 }
8344 run_test 61b "mmap() of unstriped file is successful"
8345
8346 # bug 2330 - insufficient obd_match error checking causes LBUG
8347 test_62() {
8348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8349
8350         f="$DIR/f62"
8351         echo foo > $f
8352         cancel_lru_locks osc
8353         lctl set_param fail_loc=0x405
8354         cat $f && error "cat succeeded, expect -EIO"
8355         lctl set_param fail_loc=0
8356 }
8357 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8358 # match every page all of the time.
8359 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8360
8361 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8362 # Though this test is irrelevant anymore, it helped to reveal some
8363 # other grant bugs (LU-4482), let's keep it.
8364 test_63a() {   # was test_63
8365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8366
8367         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8368
8369         for i in `seq 10` ; do
8370                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8371                 sleep 5
8372                 kill $!
8373                 sleep 1
8374         done
8375
8376         rm -f $DIR/f63 || true
8377 }
8378 run_test 63a "Verify oig_wait interruption does not crash ======="
8379
8380 # bug 2248 - async write errors didn't return to application on sync
8381 # bug 3677 - async write errors left page locked
8382 test_63b() {
8383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8384
8385         debugsave
8386         lctl set_param debug=-1
8387
8388         # ensure we have a grant to do async writes
8389         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8390         rm $DIR/$tfile
8391
8392         sync    # sync lest earlier test intercept the fail_loc
8393
8394         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8395         lctl set_param fail_loc=0x80000406
8396         $MULTIOP $DIR/$tfile Owy && \
8397                 error "sync didn't return ENOMEM"
8398         sync; sleep 2; sync     # do a real sync this time to flush page
8399         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8400                 error "locked page left in cache after async error" || true
8401         debugrestore
8402 }
8403 run_test 63b "async write errors should be returned to fsync ==="
8404
8405 test_64a () {
8406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8407
8408         lfs df $DIR
8409         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8410 }
8411 run_test 64a "verify filter grant calculations (in kernel) ====="
8412
8413 test_64b () {
8414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8415
8416         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8417 }
8418 run_test 64b "check out-of-space detection on client"
8419
8420 test_64c() {
8421         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8422 }
8423 run_test 64c "verify grant shrink"
8424
8425 import_param() {
8426         local tgt=$1
8427         local param=$2
8428
8429         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8430 }
8431
8432 # this does exactly what osc_request.c:osc_announce_cached() does in
8433 # order to calculate max amount of grants to ask from server
8434 want_grant() {
8435         local tgt=$1
8436
8437         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8438         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8439
8440         ((rpc_in_flight++));
8441         nrpages=$((nrpages * rpc_in_flight))
8442
8443         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8444
8445         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8446
8447         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8448         local undirty=$((nrpages * PAGE_SIZE))
8449
8450         local max_extent_pages
8451         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8452         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8453         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8454         local grant_extent_tax
8455         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8456
8457         undirty=$((undirty + nrextents * grant_extent_tax))
8458
8459         echo $undirty
8460 }
8461
8462 # this is size of unit for grant allocation. It should be equal to
8463 # what tgt_grant.c:tgt_grant_chunk() calculates
8464 grant_chunk() {
8465         local tgt=$1
8466         local max_brw_size
8467         local grant_extent_tax
8468
8469         max_brw_size=$(import_param $tgt max_brw_size)
8470
8471         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8472
8473         echo $(((max_brw_size + grant_extent_tax) * 2))
8474 }
8475
8476 test_64d() {
8477         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8478                 skip "OST < 2.10.55 doesn't limit grants enough"
8479
8480         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8481
8482         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8483                 skip "no grant_param connect flag"
8484
8485         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8486
8487         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8488         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8489
8490
8491         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8492         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8493
8494         $LFS setstripe $DIR/$tfile -i 0 -c 1
8495         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8496         ddpid=$!
8497
8498         while kill -0 $ddpid; do
8499                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8500
8501                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8502                         kill $ddpid
8503                         error "cur_grant $cur_grant > $max_cur_granted"
8504                 fi
8505
8506                 sleep 1
8507         done
8508 }
8509 run_test 64d "check grant limit exceed"
8510
8511 check_grants() {
8512         local tgt=$1
8513         local expected=$2
8514         local msg=$3
8515         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8516
8517         ((cur_grants == expected)) ||
8518                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8519 }
8520
8521 round_up_p2() {
8522         echo $((($1 + $2 - 1) & ~($2 - 1)))
8523 }
8524
8525 test_64e() {
8526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8527         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8528                 skip "Need OSS version at least 2.11.56"
8529
8530         # Remount client to reset grant
8531         remount_client $MOUNT || error "failed to remount client"
8532         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8533
8534         local init_grants=$(import_param $osc_tgt initial_grant)
8535
8536         check_grants $osc_tgt $init_grants "init grants"
8537
8538         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8539         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8540         local gbs=$(import_param $osc_tgt grant_block_size)
8541
8542         # write random number of bytes from max_brw_size / 4 to max_brw_size
8543         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8544         # align for direct io
8545         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8546         # round to grant consumption unit
8547         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8548
8549         local grants=$((wb_round_up + extent_tax))
8550
8551         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8552
8553         # define OBD_FAIL_TGT_NO_GRANT 0x725
8554         # make the server not grant more back
8555         do_facet ost1 $LCTL set_param fail_loc=0x725
8556         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8557
8558         do_facet ost1 $LCTL set_param fail_loc=0
8559
8560         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8561
8562         rm -f $DIR/$tfile || error "rm failed"
8563
8564         # Remount client to reset grant
8565         remount_client $MOUNT || error "failed to remount client"
8566         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8567
8568         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8569
8570         # define OBD_FAIL_TGT_NO_GRANT 0x725
8571         # make the server not grant more back
8572         do_facet ost1 $LCTL set_param fail_loc=0x725
8573         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8574         do_facet ost1 $LCTL set_param fail_loc=0
8575
8576         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8577 }
8578 run_test 64e "check grant consumption (no grant allocation)"
8579
8580 test_64f() {
8581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8582
8583         # Remount client to reset grant
8584         remount_client $MOUNT || error "failed to remount client"
8585         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8586
8587         local init_grants=$(import_param $osc_tgt initial_grant)
8588         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8589         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8590         local gbs=$(import_param $osc_tgt grant_block_size)
8591         local chunk=$(grant_chunk $osc_tgt)
8592
8593         # write random number of bytes from max_brw_size / 4 to max_brw_size
8594         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8595         # align for direct io
8596         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8597         # round to grant consumption unit
8598         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8599
8600         local grants=$((wb_round_up + extent_tax))
8601
8602         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8603         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8604                 error "error writing to $DIR/$tfile"
8605
8606         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8607                 "direct io with grant allocation"
8608
8609         rm -f $DIR/$tfile || error "rm failed"
8610
8611         # Remount client to reset grant
8612         remount_client $MOUNT || error "failed to remount client"
8613         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8614
8615         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8616
8617         local cmd="oO_WRONLY:w${write_bytes}_yc"
8618
8619         $MULTIOP $DIR/$tfile $cmd &
8620         MULTIPID=$!
8621         sleep 1
8622
8623         check_grants $osc_tgt $((init_grants - grants)) \
8624                 "buffered io, not write rpc"
8625
8626         kill -USR1 $MULTIPID
8627         wait
8628
8629         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8630                 "buffered io, one RPC"
8631 }
8632 run_test 64f "check grant consumption (with grant allocation)"
8633
8634 # bug 1414 - set/get directories' stripe info
8635 test_65a() {
8636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8637
8638         test_mkdir $DIR/$tdir
8639         touch $DIR/$tdir/f1
8640         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8641 }
8642 run_test 65a "directory with no stripe info"
8643
8644 test_65b() {
8645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8646
8647         test_mkdir $DIR/$tdir
8648         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8649
8650         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8651                                                 error "setstripe"
8652         touch $DIR/$tdir/f2
8653         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8654 }
8655 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8656
8657 test_65c() {
8658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8659         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8660
8661         test_mkdir $DIR/$tdir
8662         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8663
8664         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8665                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8666         touch $DIR/$tdir/f3
8667         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8668 }
8669 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8670
8671 test_65d() {
8672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8673
8674         test_mkdir $DIR/$tdir
8675         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8676         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8677
8678         if [[ $STRIPECOUNT -le 0 ]]; then
8679                 sc=1
8680         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8681                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8682                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8683         else
8684                 sc=$(($STRIPECOUNT - 1))
8685         fi
8686         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8687         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8688         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8689                 error "lverify failed"
8690 }
8691 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8692
8693 test_65e() {
8694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8695
8696         test_mkdir $DIR/$tdir
8697
8698         $LFS setstripe $DIR/$tdir || error "setstripe"
8699         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8700                                         error "no stripe info failed"
8701         touch $DIR/$tdir/f6
8702         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8703 }
8704 run_test 65e "directory setstripe defaults"
8705
8706 test_65f() {
8707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8708
8709         test_mkdir $DIR/${tdir}f
8710         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8711                 error "setstripe succeeded" || true
8712 }
8713 run_test 65f "dir setstripe permission (should return error) ==="
8714
8715 test_65g() {
8716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8717
8718         test_mkdir $DIR/$tdir
8719         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8720
8721         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8722                 error "setstripe -S failed"
8723         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8724         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8725                 error "delete default stripe failed"
8726 }
8727 run_test 65g "directory setstripe -d"
8728
8729 test_65h() {
8730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8731
8732         test_mkdir $DIR/$tdir
8733         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8734
8735         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8736                 error "setstripe -S failed"
8737         test_mkdir $DIR/$tdir/dd1
8738         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8739                 error "stripe info inherit failed"
8740 }
8741 run_test 65h "directory stripe info inherit ===================="
8742
8743 test_65i() {
8744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8745
8746         save_layout_restore_at_exit $MOUNT
8747
8748         # bug6367: set non-default striping on root directory
8749         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8750
8751         # bug12836: getstripe on -1 default directory striping
8752         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8753
8754         # bug12836: getstripe -v on -1 default directory striping
8755         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8756
8757         # bug12836: new find on -1 default directory striping
8758         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8759 }
8760 run_test 65i "various tests to set root directory striping"
8761
8762 test_65j() { # bug6367
8763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8764
8765         sync; sleep 1
8766
8767         # if we aren't already remounting for each test, do so for this test
8768         if [ "$I_MOUNTED" = "yes" ]; then
8769                 cleanup || error "failed to unmount"
8770                 setup
8771         fi
8772
8773         save_layout_restore_at_exit $MOUNT
8774
8775         $LFS setstripe -d $MOUNT || error "setstripe failed"
8776 }
8777 run_test 65j "set default striping on root directory (bug 6367)="
8778
8779 cleanup_65k() {
8780         rm -rf $DIR/$tdir
8781         wait_delete_completed
8782         do_facet $SINGLEMDS "lctl set_param -n \
8783                 osp.$ost*MDT0000.max_create_count=$max_count"
8784         do_facet $SINGLEMDS "lctl set_param -n \
8785                 osp.$ost*MDT0000.create_count=$count"
8786         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8787         echo $INACTIVE_OSC "is Activate"
8788
8789         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8790 }
8791
8792 test_65k() { # bug11679
8793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8794         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8795         remote_mds_nodsh && skip "remote MDS with nodsh"
8796
8797         local disable_precreate=true
8798         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8799                 disable_precreate=false
8800
8801         echo "Check OST status: "
8802         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8803                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8804
8805         for OSC in $MDS_OSCS; do
8806                 echo $OSC "is active"
8807                 do_facet $SINGLEMDS lctl --device %$OSC activate
8808         done
8809
8810         for INACTIVE_OSC in $MDS_OSCS; do
8811                 local ost=$(osc_to_ost $INACTIVE_OSC)
8812                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8813                                lov.*md*.target_obd |
8814                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8815
8816                 mkdir -p $DIR/$tdir
8817                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8818                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8819
8820                 echo "Deactivate: " $INACTIVE_OSC
8821                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8822
8823                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8824                               osp.$ost*MDT0000.create_count")
8825                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8826                                   osp.$ost*MDT0000.max_create_count")
8827                 $disable_precreate &&
8828                         do_facet $SINGLEMDS "lctl set_param -n \
8829                                 osp.$ost*MDT0000.max_create_count=0"
8830
8831                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8832                         [ -f $DIR/$tdir/$idx ] && continue
8833                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8834                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8835                                 { cleanup_65k;
8836                                   error "setstripe $idx should succeed"; }
8837                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8838                 done
8839                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8840                 rmdir $DIR/$tdir
8841
8842                 do_facet $SINGLEMDS "lctl set_param -n \
8843                         osp.$ost*MDT0000.max_create_count=$max_count"
8844                 do_facet $SINGLEMDS "lctl set_param -n \
8845                         osp.$ost*MDT0000.create_count=$count"
8846                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8847                 echo $INACTIVE_OSC "is Activate"
8848
8849                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8850         done
8851 }
8852 run_test 65k "validate manual striping works properly with deactivated OSCs"
8853
8854 test_65l() { # bug 12836
8855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8856
8857         test_mkdir -p $DIR/$tdir/test_dir
8858         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8859         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8860 }
8861 run_test 65l "lfs find on -1 stripe dir ========================"
8862
8863 test_65m() {
8864         local layout=$(save_layout $MOUNT)
8865         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8866                 restore_layout $MOUNT $layout
8867                 error "setstripe should fail by non-root users"
8868         }
8869         true
8870 }
8871 run_test 65m "normal user can't set filesystem default stripe"
8872
8873 test_65n() {
8874         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8875         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8876                 skip "Need MDS version at least 2.12.50"
8877         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8878
8879         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8880         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8881         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8882
8883         save_layout_restore_at_exit $MOUNT
8884
8885         # new subdirectory under root directory should not inherit
8886         # the default layout from root
8887         local dir1=$MOUNT/$tdir-1
8888         mkdir $dir1 || error "mkdir $dir1 failed"
8889         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8890                 error "$dir1 shouldn't have LOV EA"
8891
8892         # delete the default layout on root directory
8893         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8894
8895         local dir2=$MOUNT/$tdir-2
8896         mkdir $dir2 || error "mkdir $dir2 failed"
8897         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8898                 error "$dir2 shouldn't have LOV EA"
8899
8900         # set a new striping pattern on root directory
8901         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8902         local new_def_stripe_size=$((def_stripe_size * 2))
8903         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8904                 error "set stripe size on $MOUNT failed"
8905
8906         # new file created in $dir2 should inherit the new stripe size from
8907         # the filesystem default
8908         local file2=$dir2/$tfile-2
8909         touch $file2 || error "touch $file2 failed"
8910
8911         local file2_stripe_size=$($LFS getstripe -S $file2)
8912         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8913         {
8914                 echo "file2_stripe_size: '$file2_stripe_size'"
8915                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8916                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8917         }
8918
8919         local dir3=$MOUNT/$tdir-3
8920         mkdir $dir3 || error "mkdir $dir3 failed"
8921         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8922         # the root layout, which is the actual default layout that will be used
8923         # when new files are created in $dir3.
8924         local dir3_layout=$(get_layout_param $dir3)
8925         local root_dir_layout=$(get_layout_param $MOUNT)
8926         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8927         {
8928                 echo "dir3_layout: '$dir3_layout'"
8929                 echo "root_dir_layout: '$root_dir_layout'"
8930                 error "$dir3 should show the default layout from $MOUNT"
8931         }
8932
8933         # set OST pool on root directory
8934         local pool=$TESTNAME
8935         pool_add $pool || error "add $pool failed"
8936         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8937                 error "add targets to $pool failed"
8938
8939         $LFS setstripe -p $pool $MOUNT ||
8940                 error "set OST pool on $MOUNT failed"
8941
8942         # new file created in $dir3 should inherit the pool from
8943         # the filesystem default
8944         local file3=$dir3/$tfile-3
8945         touch $file3 || error "touch $file3 failed"
8946
8947         local file3_pool=$($LFS getstripe -p $file3)
8948         [[ "$file3_pool" = "$pool" ]] ||
8949                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8950
8951         local dir4=$MOUNT/$tdir-4
8952         mkdir $dir4 || error "mkdir $dir4 failed"
8953         local dir4_layout=$(get_layout_param $dir4)
8954         root_dir_layout=$(get_layout_param $MOUNT)
8955         echo "$LFS getstripe -d $dir4"
8956         $LFS getstripe -d $dir4
8957         echo "$LFS getstripe -d $MOUNT"
8958         $LFS getstripe -d $MOUNT
8959         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8960         {
8961                 echo "dir4_layout: '$dir4_layout'"
8962                 echo "root_dir_layout: '$root_dir_layout'"
8963                 error "$dir4 should show the default layout from $MOUNT"
8964         }
8965
8966         # new file created in $dir4 should inherit the pool from
8967         # the filesystem default
8968         local file4=$dir4/$tfile-4
8969         touch $file4 || error "touch $file4 failed"
8970
8971         local file4_pool=$($LFS getstripe -p $file4)
8972         [[ "$file4_pool" = "$pool" ]] ||
8973                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8974
8975         # new subdirectory under non-root directory should inherit
8976         # the default layout from its parent directory
8977         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8978                 error "set directory layout on $dir4 failed"
8979
8980         local dir5=$dir4/$tdir-5
8981         mkdir $dir5 || error "mkdir $dir5 failed"
8982
8983         dir4_layout=$(get_layout_param $dir4)
8984         local dir5_layout=$(get_layout_param $dir5)
8985         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8986         {
8987                 echo "dir4_layout: '$dir4_layout'"
8988                 echo "dir5_layout: '$dir5_layout'"
8989                 error "$dir5 should inherit the default layout from $dir4"
8990         }
8991
8992         # though subdir under ROOT doesn't inherit default layout, but
8993         # its sub dir/file should be created with default layout.
8994         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8995         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8996                 skip "Need MDS version at least 2.12.59"
8997
8998         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8999         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9000         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9001
9002         if [ $default_lmv_hash == "none" ]; then
9003                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9004         else
9005                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9006                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9007         fi
9008
9009         $LFS setdirstripe -D -c 2 $MOUNT ||
9010                 error "setdirstripe -D -c 2 failed"
9011         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9012         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9013         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9014 }
9015 run_test 65n "don't inherit default layout from root for new subdirectories"
9016
9017 # bug 2543 - update blocks count on client
9018 test_66() {
9019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9020
9021         COUNT=${COUNT:-8}
9022         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9023         sync; sync_all_data; sync; sync_all_data
9024         cancel_lru_locks osc
9025         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9026         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9027 }
9028 run_test 66 "update inode blocks count on client ==============="
9029
9030 meminfo() {
9031         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9032 }
9033
9034 swap_used() {
9035         swapon -s | awk '($1 == "'$1'") { print $4 }'
9036 }
9037
9038 # bug5265, obdfilter oa2dentry return -ENOENT
9039 # #define OBD_FAIL_SRV_ENOENT 0x217
9040 test_69() {
9041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9042         remote_ost_nodsh && skip "remote OST with nodsh"
9043
9044         f="$DIR/$tfile"
9045         $LFS setstripe -c 1 -i 0 $f
9046
9047         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9048
9049         do_facet ost1 lctl set_param fail_loc=0x217
9050         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9051         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9052
9053         do_facet ost1 lctl set_param fail_loc=0
9054         $DIRECTIO write $f 0 2 || error "write error"
9055
9056         cancel_lru_locks osc
9057         $DIRECTIO read $f 0 1 || error "read error"
9058
9059         do_facet ost1 lctl set_param fail_loc=0x217
9060         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9061
9062         do_facet ost1 lctl set_param fail_loc=0
9063         rm -f $f
9064 }
9065 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9066
9067 test_71() {
9068         test_mkdir $DIR/$tdir
9069         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9070         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9071 }
9072 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9073
9074 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9076         [ "$RUNAS_ID" = "$UID" ] &&
9077                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9078         # Check that testing environment is properly set up. Skip if not
9079         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9080                 skip_env "User $RUNAS_ID does not exist - skipping"
9081
9082         touch $DIR/$tfile
9083         chmod 777 $DIR/$tfile
9084         chmod ug+s $DIR/$tfile
9085         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9086                 error "$RUNAS dd $DIR/$tfile failed"
9087         # See if we are still setuid/sgid
9088         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9089                 error "S/gid is not dropped on write"
9090         # Now test that MDS is updated too
9091         cancel_lru_locks mdc
9092         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9093                 error "S/gid is not dropped on MDS"
9094         rm -f $DIR/$tfile
9095 }
9096 run_test 72a "Test that remove suid works properly (bug5695) ===="
9097
9098 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9099         local perm
9100
9101         [ "$RUNAS_ID" = "$UID" ] &&
9102                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9103         [ "$RUNAS_ID" -eq 0 ] &&
9104                 skip_env "RUNAS_ID = 0 -- skipping"
9105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9106         # Check that testing environment is properly set up. Skip if not
9107         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9108                 skip_env "User $RUNAS_ID does not exist - skipping"
9109
9110         touch $DIR/${tfile}-f{g,u}
9111         test_mkdir $DIR/${tfile}-dg
9112         test_mkdir $DIR/${tfile}-du
9113         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9114         chmod g+s $DIR/${tfile}-{f,d}g
9115         chmod u+s $DIR/${tfile}-{f,d}u
9116         for perm in 777 2777 4777; do
9117                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9118                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9119                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9120                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9121         done
9122         true
9123 }
9124 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9125
9126 # bug 3462 - multiple simultaneous MDC requests
9127 test_73() {
9128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9129
9130         test_mkdir $DIR/d73-1
9131         test_mkdir $DIR/d73-2
9132         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9133         pid1=$!
9134
9135         lctl set_param fail_loc=0x80000129
9136         $MULTIOP $DIR/d73-1/f73-2 Oc &
9137         sleep 1
9138         lctl set_param fail_loc=0
9139
9140         $MULTIOP $DIR/d73-2/f73-3 Oc &
9141         pid3=$!
9142
9143         kill -USR1 $pid1
9144         wait $pid1 || return 1
9145
9146         sleep 25
9147
9148         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9149         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9150         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9151
9152         rm -rf $DIR/d73-*
9153 }
9154 run_test 73 "multiple MDC requests (should not deadlock)"
9155
9156 test_74a() { # bug 6149, 6184
9157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9158
9159         touch $DIR/f74a
9160         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9161         #
9162         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9163         # will spin in a tight reconnection loop
9164         $LCTL set_param fail_loc=0x8000030e
9165         # get any lock that won't be difficult - lookup works.
9166         ls $DIR/f74a
9167         $LCTL set_param fail_loc=0
9168         rm -f $DIR/f74a
9169         true
9170 }
9171 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9172
9173 test_74b() { # bug 13310
9174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9175
9176         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9177         #
9178         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9179         # will spin in a tight reconnection loop
9180         $LCTL set_param fail_loc=0x8000030e
9181         # get a "difficult" lock
9182         touch $DIR/f74b
9183         $LCTL set_param fail_loc=0
9184         rm -f $DIR/f74b
9185         true
9186 }
9187 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9188
9189 test_74c() {
9190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9191
9192         #define OBD_FAIL_LDLM_NEW_LOCK
9193         $LCTL set_param fail_loc=0x319
9194         touch $DIR/$tfile && error "touch successful"
9195         $LCTL set_param fail_loc=0
9196         true
9197 }
9198 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9199
9200 slab_lic=/sys/kernel/slab/lustre_inode_cache
9201 num_objects() {
9202         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9203         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9204                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9205 }
9206
9207 test_76a() { # Now for b=20433, added originally in b=1443
9208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9209
9210         cancel_lru_locks osc
9211         # there may be some slab objects cached per core
9212         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9213         local before=$(num_objects)
9214         local count=$((512 * cpus))
9215         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9216         local margin=$((count / 10))
9217         if [[ -f $slab_lic/aliases ]]; then
9218                 local aliases=$(cat $slab_lic/aliases)
9219                 (( aliases > 0 )) && margin=$((margin * aliases))
9220         fi
9221
9222         echo "before slab objects: $before"
9223         for i in $(seq $count); do
9224                 touch $DIR/$tfile
9225                 rm -f $DIR/$tfile
9226         done
9227         cancel_lru_locks osc
9228         local after=$(num_objects)
9229         echo "created: $count, after slab objects: $after"
9230         # shared slab counts are not very accurate, allow significant margin
9231         # the main goal is that the cache growth is not permanently > $count
9232         while (( after > before + margin )); do
9233                 sleep 1
9234                 after=$(num_objects)
9235                 wait=$((wait + 1))
9236                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9237                 if (( wait > 60 )); then
9238                         error "inode slab grew from $before+$margin to $after"
9239                 fi
9240         done
9241 }
9242 run_test 76a "confirm clients recycle inodes properly ===="
9243
9244 test_76b() {
9245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9246         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9247
9248         local count=512
9249         local before=$(num_objects)
9250
9251         for i in $(seq $count); do
9252                 mkdir $DIR/$tdir
9253                 rmdir $DIR/$tdir
9254         done
9255
9256         local after=$(num_objects)
9257         local wait=0
9258
9259         while (( after > before )); do
9260                 sleep 1
9261                 after=$(num_objects)
9262                 wait=$((wait + 1))
9263                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9264                 if (( wait > 60 )); then
9265                         error "inode slab grew from $before to $after"
9266                 fi
9267         done
9268
9269         echo "slab objects before: $before, after: $after"
9270 }
9271 run_test 76b "confirm clients recycle directory inodes properly ===="
9272
9273 export ORIG_CSUM=""
9274 set_checksums()
9275 {
9276         # Note: in sptlrpc modes which enable its own bulk checksum, the
9277         # original crc32_le bulk checksum will be automatically disabled,
9278         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9279         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9280         # In this case set_checksums() will not be no-op, because sptlrpc
9281         # bulk checksum will be enabled all through the test.
9282
9283         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9284         lctl set_param -n osc.*.checksums $1
9285         return 0
9286 }
9287
9288 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9289                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9290 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9291                              tr -d [] | head -n1)}
9292 set_checksum_type()
9293 {
9294         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9295         rc=$?
9296         log "set checksum type to $1, rc = $rc"
9297         return $rc
9298 }
9299
9300 get_osc_checksum_type()
9301 {
9302         # arugment 1: OST name, like OST0000
9303         ost=$1
9304         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9305                         sed 's/.*\[\(.*\)\].*/\1/g')
9306         rc=$?
9307         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9308         echo $checksum_type
9309 }
9310
9311 F77_TMP=$TMP/f77-temp
9312 F77SZ=8
9313 setup_f77() {
9314         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9315                 error "error writing to $F77_TMP"
9316 }
9317
9318 test_77a() { # bug 10889
9319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9320         $GSS && skip_env "could not run with gss"
9321
9322         [ ! -f $F77_TMP ] && setup_f77
9323         set_checksums 1
9324         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9325         set_checksums 0
9326         rm -f $DIR/$tfile
9327 }
9328 run_test 77a "normal checksum read/write operation"
9329
9330 test_77b() { # bug 10889
9331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9332         $GSS && skip_env "could not run with gss"
9333
9334         [ ! -f $F77_TMP ] && setup_f77
9335         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9336         $LCTL set_param fail_loc=0x80000409
9337         set_checksums 1
9338
9339         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9340                 error "dd error: $?"
9341         $LCTL set_param fail_loc=0
9342
9343         for algo in $CKSUM_TYPES; do
9344                 cancel_lru_locks osc
9345                 set_checksum_type $algo
9346                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9347                 $LCTL set_param fail_loc=0x80000408
9348                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9349                 $LCTL set_param fail_loc=0
9350         done
9351         set_checksums 0
9352         set_checksum_type $ORIG_CSUM_TYPE
9353         rm -f $DIR/$tfile
9354 }
9355 run_test 77b "checksum error on client write, read"
9356
9357 cleanup_77c() {
9358         trap 0
9359         set_checksums 0
9360         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9361         $check_ost &&
9362                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9363         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9364         $check_ost && [ -n "$ost_file_prefix" ] &&
9365                 do_facet ost1 rm -f ${ost_file_prefix}\*
9366 }
9367
9368 test_77c() {
9369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9370         $GSS && skip_env "could not run with gss"
9371         remote_ost_nodsh && skip "remote OST with nodsh"
9372
9373         local bad1
9374         local osc_file_prefix
9375         local osc_file
9376         local check_ost=false
9377         local ost_file_prefix
9378         local ost_file
9379         local orig_cksum
9380         local dump_cksum
9381         local fid
9382
9383         # ensure corruption will occur on first OSS/OST
9384         $LFS setstripe -i 0 $DIR/$tfile
9385
9386         [ ! -f $F77_TMP ] && setup_f77
9387         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9388                 error "dd write error: $?"
9389         fid=$($LFS path2fid $DIR/$tfile)
9390
9391         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9392         then
9393                 check_ost=true
9394                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9395                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9396         else
9397                 echo "OSS do not support bulk pages dump upon error"
9398         fi
9399
9400         osc_file_prefix=$($LCTL get_param -n debug_path)
9401         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9402
9403         trap cleanup_77c EXIT
9404
9405         set_checksums 1
9406         # enable bulk pages dump upon error on Client
9407         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9408         # enable bulk pages dump upon error on OSS
9409         $check_ost &&
9410                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9411
9412         # flush Client cache to allow next read to reach OSS
9413         cancel_lru_locks osc
9414
9415         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9416         $LCTL set_param fail_loc=0x80000408
9417         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9418         $LCTL set_param fail_loc=0
9419
9420         rm -f $DIR/$tfile
9421
9422         # check cksum dump on Client
9423         osc_file=$(ls ${osc_file_prefix}*)
9424         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9425         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9426         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9427         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9428         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9429                      cksum)
9430         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9431         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9432                 error "dump content does not match on Client"
9433
9434         $check_ost || skip "No need to check cksum dump on OSS"
9435
9436         # check cksum dump on OSS
9437         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9438         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9439         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9440         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9441         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9442                 error "dump content does not match on OSS"
9443
9444         cleanup_77c
9445 }
9446 run_test 77c "checksum error on client read with debug"
9447
9448 test_77d() { # bug 10889
9449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9450         $GSS && skip_env "could not run with gss"
9451
9452         stack_trap "rm -f $DIR/$tfile"
9453         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9454         $LCTL set_param fail_loc=0x80000409
9455         set_checksums 1
9456         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9457                 error "direct write: rc=$?"
9458         $LCTL set_param fail_loc=0
9459         set_checksums 0
9460
9461         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9462         $LCTL set_param fail_loc=0x80000408
9463         set_checksums 1
9464         cancel_lru_locks osc
9465         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9466                 error "direct read: rc=$?"
9467         $LCTL set_param fail_loc=0
9468         set_checksums 0
9469 }
9470 run_test 77d "checksum error on OST direct write, read"
9471
9472 test_77f() { # bug 10889
9473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9474         $GSS && skip_env "could not run with gss"
9475
9476         set_checksums 1
9477         stack_trap "rm -f $DIR/$tfile"
9478         for algo in $CKSUM_TYPES; do
9479                 cancel_lru_locks osc
9480                 set_checksum_type $algo
9481                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9482                 $LCTL set_param fail_loc=0x409
9483                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9484                         error "direct write succeeded"
9485                 $LCTL set_param fail_loc=0
9486         done
9487         set_checksum_type $ORIG_CSUM_TYPE
9488         set_checksums 0
9489 }
9490 run_test 77f "repeat checksum error on write (expect error)"
9491
9492 test_77g() { # bug 10889
9493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9494         $GSS && skip_env "could not run with gss"
9495         remote_ost_nodsh && skip "remote OST with nodsh"
9496
9497         [ ! -f $F77_TMP ] && setup_f77
9498
9499         local file=$DIR/$tfile
9500         stack_trap "rm -f $file" EXIT
9501
9502         $LFS setstripe -c 1 -i 0 $file
9503         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9504         do_facet ost1 lctl set_param fail_loc=0x8000021a
9505         set_checksums 1
9506         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9507                 error "write error: rc=$?"
9508         do_facet ost1 lctl set_param fail_loc=0
9509         set_checksums 0
9510
9511         cancel_lru_locks osc
9512         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9513         do_facet ost1 lctl set_param fail_loc=0x8000021b
9514         set_checksums 1
9515         cmp $F77_TMP $file || error "file compare failed"
9516         do_facet ost1 lctl set_param fail_loc=0
9517         set_checksums 0
9518 }
9519 run_test 77g "checksum error on OST write, read"
9520
9521 test_77k() { # LU-10906
9522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9523         $GSS && skip_env "could not run with gss"
9524
9525         local cksum_param="osc.$FSNAME*.checksums"
9526         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9527         local checksum
9528         local i
9529
9530         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9531         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9532         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9533
9534         for i in 0 1; do
9535                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9536                         error "failed to set checksum=$i on MGS"
9537                 wait_update $HOSTNAME "$get_checksum" $i
9538                 #remount
9539                 echo "remount client, checksum should be $i"
9540                 remount_client $MOUNT || error "failed to remount client"
9541                 checksum=$(eval $get_checksum)
9542                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9543         done
9544         # remove persistent param to avoid races with checksum mountopt below
9545         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9546                 error "failed to delete checksum on MGS"
9547
9548         for opt in "checksum" "nochecksum"; do
9549                 #remount with mount option
9550                 echo "remount client with option $opt, checksum should be $i"
9551                 umount_client $MOUNT || error "failed to umount client"
9552                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9553                         error "failed to mount client with option '$opt'"
9554                 checksum=$(eval $get_checksum)
9555                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9556                 i=$((i - 1))
9557         done
9558
9559         remount_client $MOUNT || error "failed to remount client"
9560 }
9561 run_test 77k "enable/disable checksum correctly"
9562
9563 test_77l() {
9564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9565         $GSS && skip_env "could not run with gss"
9566
9567         set_checksums 1
9568         stack_trap "set_checksums $ORIG_CSUM" EXIT
9569         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9570
9571         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9572
9573         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9574         for algo in $CKSUM_TYPES; do
9575                 set_checksum_type $algo || error "fail to set checksum type $algo"
9576                 osc_algo=$(get_osc_checksum_type OST0000)
9577                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9578
9579                 # no locks, no reqs to let the connection idle
9580                 cancel_lru_locks osc
9581                 lru_resize_disable osc
9582                 wait_osc_import_state client ost1 IDLE
9583
9584                 # ensure ost1 is connected
9585                 stat $DIR/$tfile >/dev/null || error "can't stat"
9586                 wait_osc_import_state client ost1 FULL
9587
9588                 osc_algo=$(get_osc_checksum_type OST0000)
9589                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9590         done
9591         return 0
9592 }
9593 run_test 77l "preferred checksum type is remembered after reconnected"
9594
9595 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9596 rm -f $F77_TMP
9597 unset F77_TMP
9598
9599 cleanup_test_78() {
9600         trap 0
9601         rm -f $DIR/$tfile
9602 }
9603
9604 test_78() { # bug 10901
9605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9606         remote_ost || skip_env "local OST"
9607
9608         NSEQ=5
9609         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9610         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9611         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9612         echo "MemTotal: $MEMTOTAL"
9613
9614         # reserve 256MB of memory for the kernel and other running processes,
9615         # and then take 1/2 of the remaining memory for the read/write buffers.
9616         if [ $MEMTOTAL -gt 512 ] ;then
9617                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9618         else
9619                 # for those poor memory-starved high-end clusters...
9620                 MEMTOTAL=$((MEMTOTAL / 2))
9621         fi
9622         echo "Mem to use for directio: $MEMTOTAL"
9623
9624         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9625         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9626         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9627         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9628                 head -n1)
9629         echo "Smallest OST: $SMALLESTOST"
9630         [[ $SMALLESTOST -lt 10240 ]] &&
9631                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9632
9633         trap cleanup_test_78 EXIT
9634
9635         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9636                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9637
9638         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9639         echo "File size: $F78SIZE"
9640         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9641         for i in $(seq 1 $NSEQ); do
9642                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9643                 echo directIO rdwr round $i of $NSEQ
9644                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9645         done
9646
9647         cleanup_test_78
9648 }
9649 run_test 78 "handle large O_DIRECT writes correctly ============"
9650
9651 test_79() { # bug 12743
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653
9654         wait_delete_completed
9655
9656         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9657         BKFREE=$(calc_osc_kbytes kbytesfree)
9658         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9659
9660         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9661         DFTOTAL=`echo $STRING | cut -d, -f1`
9662         DFUSED=`echo $STRING  | cut -d, -f2`
9663         DFAVAIL=`echo $STRING | cut -d, -f3`
9664         DFFREE=$(($DFTOTAL - $DFUSED))
9665
9666         ALLOWANCE=$((64 * $OSTCOUNT))
9667
9668         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9669            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9670                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9671         fi
9672         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9673            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9674                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9675         fi
9676         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9677            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9678                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9679         fi
9680 }
9681 run_test 79 "df report consistency check ======================="
9682
9683 test_80() { # bug 10718
9684         remote_ost_nodsh && skip "remote OST with nodsh"
9685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9686
9687         # relax strong synchronous semantics for slow backends like ZFS
9688         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9689                 local soc="obdfilter.*.sync_lock_cancel"
9690                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9691
9692                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9693                 if [ -z "$save" ]; then
9694                         soc="obdfilter.*.sync_on_lock_cancel"
9695                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9696                 fi
9697
9698                 if [ "$save" != "never" ]; then
9699                         local hosts=$(comma_list $(osts_nodes))
9700
9701                         do_nodes $hosts $LCTL set_param $soc=never
9702                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9703                 fi
9704         fi
9705
9706         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9707         sync; sleep 1; sync
9708         local before=$(date +%s)
9709         cancel_lru_locks osc
9710         local after=$(date +%s)
9711         local diff=$((after - before))
9712         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9713
9714         rm -f $DIR/$tfile
9715 }
9716 run_test 80 "Page eviction is equally fast at high offsets too"
9717
9718 test_81a() { # LU-456
9719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9720         remote_ost_nodsh && skip "remote OST with nodsh"
9721
9722         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9723         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9724         do_facet ost1 lctl set_param fail_loc=0x80000228
9725
9726         # write should trigger a retry and success
9727         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9728         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9729         RC=$?
9730         if [ $RC -ne 0 ] ; then
9731                 error "write should success, but failed for $RC"
9732         fi
9733 }
9734 run_test 81a "OST should retry write when get -ENOSPC ==============="
9735
9736 test_81b() { # LU-456
9737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9738         remote_ost_nodsh && skip "remote OST with nodsh"
9739
9740         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9741         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9742         do_facet ost1 lctl set_param fail_loc=0x228
9743
9744         # write should retry several times and return -ENOSPC finally
9745         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9746         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9747         RC=$?
9748         ENOSPC=28
9749         if [ $RC -ne $ENOSPC ] ; then
9750                 error "dd should fail for -ENOSPC, but succeed."
9751         fi
9752 }
9753 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9754
9755 test_99() {
9756         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9757
9758         test_mkdir $DIR/$tdir.cvsroot
9759         chown $RUNAS_ID $DIR/$tdir.cvsroot
9760
9761         cd $TMP
9762         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9763
9764         cd /etc/init.d
9765         # some versions of cvs import exit(1) when asked to import links or
9766         # files they can't read.  ignore those files.
9767         local toignore=$(find . -type l -printf '-I %f\n' -o \
9768                          ! -perm /4 -printf '-I %f\n')
9769         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9770                 $tdir.reposname vtag rtag
9771
9772         cd $DIR
9773         test_mkdir $DIR/$tdir.reposname
9774         chown $RUNAS_ID $DIR/$tdir.reposname
9775         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9776
9777         cd $DIR/$tdir.reposname
9778         $RUNAS touch foo99
9779         $RUNAS cvs add -m 'addmsg' foo99
9780         $RUNAS cvs update
9781         $RUNAS cvs commit -m 'nomsg' foo99
9782         rm -fr $DIR/$tdir.cvsroot
9783 }
9784 run_test 99 "cvs strange file/directory operations"
9785
9786 test_100() {
9787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9788         [[ "$NETTYPE" =~ tcp ]] ||
9789                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9790         remote_ost_nodsh && skip "remote OST with nodsh"
9791         remote_mds_nodsh && skip "remote MDS with nodsh"
9792         remote_servers ||
9793                 skip "useless for local single node setup"
9794
9795         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9796                 [ "$PROT" != "tcp" ] && continue
9797                 RPORT=$(echo $REMOTE | cut -d: -f2)
9798                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9799
9800                 rc=0
9801                 LPORT=`echo $LOCAL | cut -d: -f2`
9802                 if [ $LPORT -ge 1024 ]; then
9803                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9804                         netstat -tna
9805                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9806                 fi
9807         done
9808         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9809 }
9810 run_test 100 "check local port using privileged port ==========="
9811
9812 function get_named_value()
9813 {
9814     local tag=$1
9815
9816     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9817 }
9818
9819 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9820                    awk '/^max_cached_mb/ { print $2 }')
9821
9822 cleanup_101a() {
9823         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9824         trap 0
9825 }
9826
9827 test_101a() {
9828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9829
9830         local s
9831         local discard
9832         local nreads=10000
9833         local cache_limit=32
9834
9835         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9836         trap cleanup_101a EXIT
9837         $LCTL set_param -n llite.*.read_ahead_stats=0
9838         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9839
9840         #
9841         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9842         #
9843         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9844         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9845
9846         discard=0
9847         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9848                    get_named_value 'read.but.discarded'); do
9849                         discard=$(($discard + $s))
9850         done
9851         cleanup_101a
9852
9853         $LCTL get_param osc.*-osc*.rpc_stats
9854         $LCTL get_param llite.*.read_ahead_stats
9855
9856         # Discard is generally zero, but sometimes a few random reads line up
9857         # and trigger larger readahead, which is wasted & leads to discards.
9858         if [[ $(($discard)) -gt $nreads ]]; then
9859                 error "too many ($discard) discarded pages"
9860         fi
9861         rm -f $DIR/$tfile || true
9862 }
9863 run_test 101a "check read-ahead for random reads"
9864
9865 setup_test101bc() {
9866         test_mkdir $DIR/$tdir
9867         local ssize=$1
9868         local FILE_LENGTH=$2
9869         STRIPE_OFFSET=0
9870
9871         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9872
9873         local list=$(comma_list $(osts_nodes))
9874         set_osd_param $list '' read_cache_enable 0
9875         set_osd_param $list '' writethrough_cache_enable 0
9876
9877         trap cleanup_test101bc EXIT
9878         # prepare the read-ahead file
9879         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9880
9881         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9882                                 count=$FILE_SIZE_MB 2> /dev/null
9883
9884 }
9885
9886 cleanup_test101bc() {
9887         trap 0
9888         rm -rf $DIR/$tdir
9889         rm -f $DIR/$tfile
9890
9891         local list=$(comma_list $(osts_nodes))
9892         set_osd_param $list '' read_cache_enable 1
9893         set_osd_param $list '' writethrough_cache_enable 1
9894 }
9895
9896 calc_total() {
9897         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9898 }
9899
9900 ra_check_101() {
9901         local READ_SIZE=$1
9902         local STRIPE_SIZE=$2
9903         local FILE_LENGTH=$3
9904         local RA_INC=1048576
9905         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9906         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9907                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9908         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9909                   get_named_value 'read.but.discarded' | calc_total)
9910         if [[ $DISCARD -gt $discard_limit ]]; then
9911                 $LCTL get_param llite.*.read_ahead_stats
9912                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9913         else
9914                 echo "Read-ahead success for size ${READ_SIZE}"
9915         fi
9916 }
9917
9918 test_101b() {
9919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9920         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9921
9922         local STRIPE_SIZE=1048576
9923         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9924
9925         if [ $SLOW == "yes" ]; then
9926                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9927         else
9928                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9929         fi
9930
9931         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9932
9933         # prepare the read-ahead file
9934         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9935         cancel_lru_locks osc
9936         for BIDX in 2 4 8 16 32 64 128 256
9937         do
9938                 local BSIZE=$((BIDX*4096))
9939                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9940                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9941                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9942                 $LCTL set_param -n llite.*.read_ahead_stats=0
9943                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9944                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9945                 cancel_lru_locks osc
9946                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9947         done
9948         cleanup_test101bc
9949         true
9950 }
9951 run_test 101b "check stride-io mode read-ahead ================="
9952
9953 test_101c() {
9954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9955
9956         local STRIPE_SIZE=1048576
9957         local FILE_LENGTH=$((STRIPE_SIZE*100))
9958         local nreads=10000
9959         local rsize=65536
9960         local osc_rpc_stats
9961
9962         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9963
9964         cancel_lru_locks osc
9965         $LCTL set_param osc.*.rpc_stats=0
9966         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9967         $LCTL get_param osc.*.rpc_stats
9968         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9969                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9970                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9971                 local size
9972
9973                 if [ $lines -le 20 ]; then
9974                         echo "continue debug"
9975                         continue
9976                 fi
9977                 for size in 1 2 4 8; do
9978                         local rpc=$(echo "$stats" |
9979                                     awk '($1 == "'$size':") {print $2; exit; }')
9980                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9981                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9982                 done
9983                 echo "$osc_rpc_stats check passed!"
9984         done
9985         cleanup_test101bc
9986         true
9987 }
9988 run_test 101c "check stripe_size aligned read-ahead"
9989
9990 test_101d() {
9991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9992
9993         local file=$DIR/$tfile
9994         local sz_MB=${FILESIZE_101d:-80}
9995         local ra_MB=${READAHEAD_MB:-40}
9996
9997         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9998         [ $free_MB -lt $sz_MB ] &&
9999                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10000
10001         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10002         $LFS setstripe -c -1 $file || error "setstripe failed"
10003
10004         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10005         echo Cancel LRU locks on lustre client to flush the client cache
10006         cancel_lru_locks osc
10007
10008         echo Disable read-ahead
10009         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10010         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10011         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10012         $LCTL get_param -n llite.*.max_read_ahead_mb
10013
10014         echo "Reading the test file $file with read-ahead disabled"
10015         local sz_KB=$((sz_MB * 1024 / 4))
10016         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10017         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10018         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10019                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10020
10021         echo "Cancel LRU locks on lustre client to flush the client cache"
10022         cancel_lru_locks osc
10023         echo Enable read-ahead with ${ra_MB}MB
10024         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10025
10026         echo "Reading the test file $file with read-ahead enabled"
10027         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10028                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10029
10030         echo "read-ahead disabled time read $raOFF"
10031         echo "read-ahead enabled time read $raON"
10032
10033         rm -f $file
10034         wait_delete_completed
10035
10036         # use awk for this check instead of bash because it handles decimals
10037         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10038                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10039 }
10040 run_test 101d "file read with and without read-ahead enabled"
10041
10042 test_101e() {
10043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10044
10045         local file=$DIR/$tfile
10046         local size_KB=500  #KB
10047         local count=100
10048         local bsize=1024
10049
10050         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10051         local need_KB=$((count * size_KB))
10052         [[ $free_KB -le $need_KB ]] &&
10053                 skip_env "Need free space $need_KB, have $free_KB"
10054
10055         echo "Creating $count ${size_KB}K test files"
10056         for ((i = 0; i < $count; i++)); do
10057                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10058         done
10059
10060         echo "Cancel LRU locks on lustre client to flush the client cache"
10061         cancel_lru_locks $OSC
10062
10063         echo "Reset readahead stats"
10064         $LCTL set_param -n llite.*.read_ahead_stats=0
10065
10066         for ((i = 0; i < $count; i++)); do
10067                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10068         done
10069
10070         $LCTL get_param llite.*.max_cached_mb
10071         $LCTL get_param llite.*.read_ahead_stats
10072         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10073                      get_named_value 'misses' | calc_total)
10074
10075         for ((i = 0; i < $count; i++)); do
10076                 rm -rf $file.$i 2>/dev/null
10077         done
10078
10079         #10000 means 20% reads are missing in readahead
10080         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10081 }
10082 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10083
10084 test_101f() {
10085         which iozone || skip_env "no iozone installed"
10086
10087         local old_debug=$($LCTL get_param debug)
10088         old_debug=${old_debug#*=}
10089         $LCTL set_param debug="reada mmap"
10090
10091         # create a test file
10092         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10093
10094         echo Cancel LRU locks on lustre client to flush the client cache
10095         cancel_lru_locks osc
10096
10097         echo Reset readahead stats
10098         $LCTL set_param -n llite.*.read_ahead_stats=0
10099
10100         echo mmap read the file with small block size
10101         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10102                 > /dev/null 2>&1
10103
10104         echo checking missing pages
10105         $LCTL get_param llite.*.read_ahead_stats
10106         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10107                         get_named_value 'misses' | calc_total)
10108
10109         $LCTL set_param debug="$old_debug"
10110         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10111         rm -f $DIR/$tfile
10112 }
10113 run_test 101f "check mmap read performance"
10114
10115 test_101g_brw_size_test() {
10116         local mb=$1
10117         local pages=$((mb * 1048576 / PAGE_SIZE))
10118         local file=$DIR/$tfile
10119
10120         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10121                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10122         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10123                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10124                         return 2
10125         done
10126
10127         stack_trap "rm -f $file" EXIT
10128         $LCTL set_param -n osc.*.rpc_stats=0
10129
10130         # 10 RPCs should be enough for the test
10131         local count=10
10132         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10133                 { error "dd write ${mb} MB blocks failed"; return 3; }
10134         cancel_lru_locks osc
10135         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10136                 { error "dd write ${mb} MB blocks failed"; return 4; }
10137
10138         # calculate number of full-sized read and write RPCs
10139         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10140                 sed -n '/pages per rpc/,/^$/p' |
10141                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10142                 END { print reads,writes }'))
10143         # allow one extra full-sized read RPC for async readahead
10144         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10145                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10146         [[ ${rpcs[1]} == $count ]] ||
10147                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10148 }
10149
10150 test_101g() {
10151         remote_ost_nodsh && skip "remote OST with nodsh"
10152
10153         local rpcs
10154         local osts=$(get_facets OST)
10155         local list=$(comma_list $(osts_nodes))
10156         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10157         local brw_size="obdfilter.*.brw_size"
10158
10159         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10160
10161         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10162
10163         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10164                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10165                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10166            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10167                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10168                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10169
10170                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10171                         suffix="M"
10172
10173                 if [[ $orig_mb -lt 16 ]]; then
10174                         save_lustre_params $osts "$brw_size" > $p
10175                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10176                                 error "set 16MB RPC size failed"
10177
10178                         echo "remount client to enable new RPC size"
10179                         remount_client $MOUNT || error "remount_client failed"
10180                 fi
10181
10182                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10183                 # should be able to set brw_size=12, but no rpc_stats for that
10184                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10185         fi
10186
10187         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10188
10189         if [[ $orig_mb -lt 16 ]]; then
10190                 restore_lustre_params < $p
10191                 remount_client $MOUNT || error "remount_client restore failed"
10192         fi
10193
10194         rm -f $p $DIR/$tfile
10195 }
10196 run_test 101g "Big bulk(4/16 MiB) readahead"
10197
10198 test_101h() {
10199         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10200
10201         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10202                 error "dd 70M file failed"
10203         echo Cancel LRU locks on lustre client to flush the client cache
10204         cancel_lru_locks osc
10205
10206         echo "Reset readahead stats"
10207         $LCTL set_param -n llite.*.read_ahead_stats 0
10208
10209         echo "Read 10M of data but cross 64M bundary"
10210         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10211         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10212                      get_named_value 'misses' | calc_total)
10213         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10214         rm -f $p $DIR/$tfile
10215 }
10216 run_test 101h "Readahead should cover current read window"
10217
10218 test_101i() {
10219         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10220                 error "dd 10M file failed"
10221
10222         local max_per_file_mb=$($LCTL get_param -n \
10223                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10224         cancel_lru_locks osc
10225         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10226         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10227                 error "set max_read_ahead_per_file_mb to 1 failed"
10228
10229         echo "Reset readahead stats"
10230         $LCTL set_param llite.*.read_ahead_stats=0
10231
10232         dd if=$DIR/$tfile of=/dev/null bs=2M
10233
10234         $LCTL get_param llite.*.read_ahead_stats
10235         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10236                      awk '/misses/ { print $2 }')
10237         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10238         rm -f $DIR/$tfile
10239 }
10240 run_test 101i "allow current readahead to exceed reservation"
10241
10242 test_101j() {
10243         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10244                 error "setstripe $DIR/$tfile failed"
10245         local file_size=$((1048576 * 16))
10246         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10247         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10248
10249         echo Disable read-ahead
10250         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10251
10252         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10253         for blk in $PAGE_SIZE 1048576 $file_size; do
10254                 cancel_lru_locks osc
10255                 echo "Reset readahead stats"
10256                 $LCTL set_param -n llite.*.read_ahead_stats=0
10257                 local count=$(($file_size / $blk))
10258                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10259                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10260                              get_named_value 'failed.to.fast.read' | calc_total)
10261                 $LCTL get_param -n llite.*.read_ahead_stats
10262                 [ $miss -eq $count ] || error "expected $count got $miss"
10263         done
10264
10265         rm -f $p $DIR/$tfile
10266 }
10267 run_test 101j "A complete read block should be submitted when no RA"
10268
10269 setup_test102() {
10270         test_mkdir $DIR/$tdir
10271         chown $RUNAS_ID $DIR/$tdir
10272         STRIPE_SIZE=65536
10273         STRIPE_OFFSET=1
10274         STRIPE_COUNT=$OSTCOUNT
10275         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10276
10277         trap cleanup_test102 EXIT
10278         cd $DIR
10279         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10280         cd $DIR/$tdir
10281         for num in 1 2 3 4; do
10282                 for count in $(seq 1 $STRIPE_COUNT); do
10283                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10284                                 local size=`expr $STRIPE_SIZE \* $num`
10285                                 local file=file"$num-$idx-$count"
10286                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10287                         done
10288                 done
10289         done
10290
10291         cd $DIR
10292         $1 tar cf $TMP/f102.tar $tdir --xattrs
10293 }
10294
10295 cleanup_test102() {
10296         trap 0
10297         rm -f $TMP/f102.tar
10298         rm -rf $DIR/d0.sanity/d102
10299 }
10300
10301 test_102a() {
10302         [ "$UID" != 0 ] && skip "must run as root"
10303         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10304                 skip_env "must have user_xattr"
10305
10306         [ -z "$(which setfattr 2>/dev/null)" ] &&
10307                 skip_env "could not find setfattr"
10308
10309         local testfile=$DIR/$tfile
10310
10311         touch $testfile
10312         echo "set/get xattr..."
10313         setfattr -n trusted.name1 -v value1 $testfile ||
10314                 error "setfattr -n trusted.name1=value1 $testfile failed"
10315         getfattr -n trusted.name1 $testfile 2> /dev/null |
10316           grep "trusted.name1=.value1" ||
10317                 error "$testfile missing trusted.name1=value1"
10318
10319         setfattr -n user.author1 -v author1 $testfile ||
10320                 error "setfattr -n user.author1=author1 $testfile failed"
10321         getfattr -n user.author1 $testfile 2> /dev/null |
10322           grep "user.author1=.author1" ||
10323                 error "$testfile missing trusted.author1=author1"
10324
10325         echo "listxattr..."
10326         setfattr -n trusted.name2 -v value2 $testfile ||
10327                 error "$testfile unable to set trusted.name2"
10328         setfattr -n trusted.name3 -v value3 $testfile ||
10329                 error "$testfile unable to set trusted.name3"
10330         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10331             grep "trusted.name" | wc -l) -eq 3 ] ||
10332                 error "$testfile missing 3 trusted.name xattrs"
10333
10334         setfattr -n user.author2 -v author2 $testfile ||
10335                 error "$testfile unable to set user.author2"
10336         setfattr -n user.author3 -v author3 $testfile ||
10337                 error "$testfile unable to set user.author3"
10338         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10339             grep "user.author" | wc -l) -eq 3 ] ||
10340                 error "$testfile missing 3 user.author xattrs"
10341
10342         echo "remove xattr..."
10343         setfattr -x trusted.name1 $testfile ||
10344                 error "$testfile error deleting trusted.name1"
10345         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10346                 error "$testfile did not delete trusted.name1 xattr"
10347
10348         setfattr -x user.author1 $testfile ||
10349                 error "$testfile error deleting user.author1"
10350         echo "set lustre special xattr ..."
10351         $LFS setstripe -c1 $testfile
10352         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10353                 awk -F "=" '/trusted.lov/ { print $2 }' )
10354         setfattr -n "trusted.lov" -v $lovea $testfile ||
10355                 error "$testfile doesn't ignore setting trusted.lov again"
10356         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10357                 error "$testfile allow setting invalid trusted.lov"
10358         rm -f $testfile
10359 }
10360 run_test 102a "user xattr test =================================="
10361
10362 check_102b_layout() {
10363         local layout="$*"
10364         local testfile=$DIR/$tfile
10365
10366         echo "test layout '$layout'"
10367         $LFS setstripe $layout $testfile || error "setstripe failed"
10368         $LFS getstripe -y $testfile
10369
10370         echo "get/set/list trusted.lov xattr ..." # b=10930
10371         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10372         [[ "$value" =~ "trusted.lov" ]] ||
10373                 error "can't get trusted.lov from $testfile"
10374         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10375                 error "getstripe failed"
10376
10377         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10378
10379         value=$(cut -d= -f2 <<<$value)
10380         # LU-13168: truncated xattr should fail if short lov_user_md header
10381         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10382                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10383         for len in $lens; do
10384                 echo "setfattr $len $testfile.2"
10385                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10386                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10387         done
10388         local stripe_size=$($LFS getstripe -S $testfile.2)
10389         local stripe_count=$($LFS getstripe -c $testfile.2)
10390         [[ $stripe_size -eq 65536 ]] ||
10391                 error "stripe size $stripe_size != 65536"
10392         [[ $stripe_count -eq $stripe_count_orig ]] ||
10393                 error "stripe count $stripe_count != $stripe_count_orig"
10394         rm $testfile $testfile.2
10395 }
10396
10397 test_102b() {
10398         [ -z "$(which setfattr 2>/dev/null)" ] &&
10399                 skip_env "could not find setfattr"
10400         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10401
10402         # check plain layout
10403         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10404
10405         # and also check composite layout
10406         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10407
10408 }
10409 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10410
10411 test_102c() {
10412         [ -z "$(which setfattr 2>/dev/null)" ] &&
10413                 skip_env "could not find setfattr"
10414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10415
10416         # b10930: get/set/list lustre.lov xattr
10417         echo "get/set/list lustre.lov xattr ..."
10418         test_mkdir $DIR/$tdir
10419         chown $RUNAS_ID $DIR/$tdir
10420         local testfile=$DIR/$tdir/$tfile
10421         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10422                 error "setstripe failed"
10423         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10424                 error "getstripe failed"
10425         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10426         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10427
10428         local testfile2=${testfile}2
10429         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10430                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10431
10432         $RUNAS $MCREATE $testfile2
10433         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10434         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10435         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10436         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10437         [ $stripe_count -eq $STRIPECOUNT ] ||
10438                 error "stripe count $stripe_count != $STRIPECOUNT"
10439 }
10440 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10441
10442 compare_stripe_info1() {
10443         local stripe_index_all_zero=true
10444
10445         for num in 1 2 3 4; do
10446                 for count in $(seq 1 $STRIPE_COUNT); do
10447                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10448                                 local size=$((STRIPE_SIZE * num))
10449                                 local file=file"$num-$offset-$count"
10450                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10451                                 [[ $stripe_size -ne $size ]] &&
10452                                     error "$file: size $stripe_size != $size"
10453                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10454                                 # allow fewer stripes to be created, ORI-601
10455                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10456                                     error "$file: count $stripe_count != $count"
10457                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10458                                 [[ $stripe_index -ne 0 ]] &&
10459                                         stripe_index_all_zero=false
10460                         done
10461                 done
10462         done
10463         $stripe_index_all_zero &&
10464                 error "all files are being extracted starting from OST index 0"
10465         return 0
10466 }
10467
10468 have_xattrs_include() {
10469         tar --help | grep -q xattrs-include &&
10470                 echo --xattrs-include="lustre.*"
10471 }
10472
10473 test_102d() {
10474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10475         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10476
10477         XINC=$(have_xattrs_include)
10478         setup_test102
10479         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10480         cd $DIR/$tdir/$tdir
10481         compare_stripe_info1
10482 }
10483 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10484
10485 test_102f() {
10486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10487         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10488
10489         XINC=$(have_xattrs_include)
10490         setup_test102
10491         test_mkdir $DIR/$tdir.restore
10492         cd $DIR
10493         tar cf - --xattrs $tdir | tar xf - \
10494                 -C $DIR/$tdir.restore --xattrs $XINC
10495         cd $DIR/$tdir.restore/$tdir
10496         compare_stripe_info1
10497 }
10498 run_test 102f "tar copy files, not keep osts"
10499
10500 grow_xattr() {
10501         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10502                 skip "must have user_xattr"
10503         [ -z "$(which setfattr 2>/dev/null)" ] &&
10504                 skip_env "could not find setfattr"
10505         [ -z "$(which getfattr 2>/dev/null)" ] &&
10506                 skip_env "could not find getfattr"
10507
10508         local xsize=${1:-1024}  # in bytes
10509         local file=$DIR/$tfile
10510         local value="$(generate_string $xsize)"
10511         local xbig=trusted.big
10512         local toobig=$2
10513
10514         touch $file
10515         log "save $xbig on $file"
10516         if [ -z "$toobig" ]
10517         then
10518                 setfattr -n $xbig -v $value $file ||
10519                         error "saving $xbig on $file failed"
10520         else
10521                 setfattr -n $xbig -v $value $file &&
10522                         error "saving $xbig on $file succeeded"
10523                 return 0
10524         fi
10525
10526         local orig=$(get_xattr_value $xbig $file)
10527         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10528
10529         local xsml=trusted.sml
10530         log "save $xsml on $file"
10531         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10532
10533         local new=$(get_xattr_value $xbig $file)
10534         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10535
10536         log "grow $xsml on $file"
10537         setfattr -n $xsml -v "$value" $file ||
10538                 error "growing $xsml on $file failed"
10539
10540         new=$(get_xattr_value $xbig $file)
10541         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10542         log "$xbig still valid after growing $xsml"
10543
10544         rm -f $file
10545 }
10546
10547 test_102h() { # bug 15777
10548         grow_xattr 1024
10549 }
10550 run_test 102h "grow xattr from inside inode to external block"
10551
10552 test_102ha() {
10553         large_xattr_enabled || skip_env "ea_inode feature disabled"
10554
10555         echo "setting xattr of max xattr size: $(max_xattr_size)"
10556         grow_xattr $(max_xattr_size)
10557
10558         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10559         echo "This should fail:"
10560         grow_xattr $(($(max_xattr_size) + 10)) 1
10561 }
10562 run_test 102ha "grow xattr from inside inode to external inode"
10563
10564 test_102i() { # bug 17038
10565         [ -z "$(which getfattr 2>/dev/null)" ] &&
10566                 skip "could not find getfattr"
10567
10568         touch $DIR/$tfile
10569         ln -s $DIR/$tfile $DIR/${tfile}link
10570         getfattr -n trusted.lov $DIR/$tfile ||
10571                 error "lgetxattr on $DIR/$tfile failed"
10572         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10573                 grep -i "no such attr" ||
10574                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10575         rm -f $DIR/$tfile $DIR/${tfile}link
10576 }
10577 run_test 102i "lgetxattr test on symbolic link ============"
10578
10579 test_102j() {
10580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10581         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10582
10583         XINC=$(have_xattrs_include)
10584         setup_test102 "$RUNAS"
10585         chown $RUNAS_ID $DIR/$tdir
10586         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10587         cd $DIR/$tdir/$tdir
10588         compare_stripe_info1 "$RUNAS"
10589 }
10590 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10591
10592 test_102k() {
10593         [ -z "$(which setfattr 2>/dev/null)" ] &&
10594                 skip "could not find setfattr"
10595
10596         touch $DIR/$tfile
10597         # b22187 just check that does not crash for regular file.
10598         setfattr -n trusted.lov $DIR/$tfile
10599         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10600         local test_kdir=$DIR/$tdir
10601         test_mkdir $test_kdir
10602         local default_size=$($LFS getstripe -S $test_kdir)
10603         local default_count=$($LFS getstripe -c $test_kdir)
10604         local default_offset=$($LFS getstripe -i $test_kdir)
10605         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10606                 error 'dir setstripe failed'
10607         setfattr -n trusted.lov $test_kdir
10608         local stripe_size=$($LFS getstripe -S $test_kdir)
10609         local stripe_count=$($LFS getstripe -c $test_kdir)
10610         local stripe_offset=$($LFS getstripe -i $test_kdir)
10611         [ $stripe_size -eq $default_size ] ||
10612                 error "stripe size $stripe_size != $default_size"
10613         [ $stripe_count -eq $default_count ] ||
10614                 error "stripe count $stripe_count != $default_count"
10615         [ $stripe_offset -eq $default_offset ] ||
10616                 error "stripe offset $stripe_offset != $default_offset"
10617         rm -rf $DIR/$tfile $test_kdir
10618 }
10619 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10620
10621 test_102l() {
10622         [ -z "$(which getfattr 2>/dev/null)" ] &&
10623                 skip "could not find getfattr"
10624
10625         # LU-532 trusted. xattr is invisible to non-root
10626         local testfile=$DIR/$tfile
10627
10628         touch $testfile
10629
10630         echo "listxattr as user..."
10631         chown $RUNAS_ID $testfile
10632         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10633             grep -q "trusted" &&
10634                 error "$testfile trusted xattrs are user visible"
10635
10636         return 0;
10637 }
10638 run_test 102l "listxattr size test =================================="
10639
10640 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10641         local path=$DIR/$tfile
10642         touch $path
10643
10644         listxattr_size_check $path || error "listattr_size_check $path failed"
10645 }
10646 run_test 102m "Ensure listxattr fails on small bufffer ========"
10647
10648 cleanup_test102
10649
10650 getxattr() { # getxattr path name
10651         # Return the base64 encoding of the value of xattr name on path.
10652         local path=$1
10653         local name=$2
10654
10655         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10656         # file: $path
10657         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10658         #
10659         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10660
10661         getfattr --absolute-names --encoding=base64 --name=$name $path |
10662                 awk -F= -v name=$name '$1 == name {
10663                         print substr($0, index($0, "=") + 1);
10664         }'
10665 }
10666
10667 test_102n() { # LU-4101 mdt: protect internal xattrs
10668         [ -z "$(which setfattr 2>/dev/null)" ] &&
10669                 skip "could not find setfattr"
10670         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10671         then
10672                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10673         fi
10674
10675         local file0=$DIR/$tfile.0
10676         local file1=$DIR/$tfile.1
10677         local xattr0=$TMP/$tfile.0
10678         local xattr1=$TMP/$tfile.1
10679         local namelist="lov lma lmv link fid version som hsm"
10680         local name
10681         local value
10682
10683         rm -rf $file0 $file1 $xattr0 $xattr1
10684         touch $file0 $file1
10685
10686         # Get 'before' xattrs of $file1.
10687         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10688
10689         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10690                 namelist+=" lfsck_namespace"
10691         for name in $namelist; do
10692                 # Try to copy xattr from $file0 to $file1.
10693                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10694
10695                 setfattr --name=trusted.$name --value="$value" $file1 ||
10696                         error "setxattr 'trusted.$name' failed"
10697
10698                 # Try to set a garbage xattr.
10699                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10700
10701                 if [[ x$name == "xlov" ]]; then
10702                         setfattr --name=trusted.lov --value="$value" $file1 &&
10703                         error "setxattr invalid 'trusted.lov' success"
10704                 else
10705                         setfattr --name=trusted.$name --value="$value" $file1 ||
10706                                 error "setxattr invalid 'trusted.$name' failed"
10707                 fi
10708
10709                 # Try to remove the xattr from $file1. We don't care if this
10710                 # appears to succeed or fail, we just don't want there to be
10711                 # any changes or crashes.
10712                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10713         done
10714
10715         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10716         then
10717                 name="lfsck_ns"
10718                 # Try to copy xattr from $file0 to $file1.
10719                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10720
10721                 setfattr --name=trusted.$name --value="$value" $file1 ||
10722                         error "setxattr 'trusted.$name' failed"
10723
10724                 # Try to set a garbage xattr.
10725                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10726
10727                 setfattr --name=trusted.$name --value="$value" $file1 ||
10728                         error "setxattr 'trusted.$name' failed"
10729
10730                 # Try to remove the xattr from $file1. We don't care if this
10731                 # appears to succeed or fail, we just don't want there to be
10732                 # any changes or crashes.
10733                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10734         fi
10735
10736         # Get 'after' xattrs of file1.
10737         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10738
10739         if ! diff $xattr0 $xattr1; then
10740                 error "before and after xattrs of '$file1' differ"
10741         fi
10742
10743         rm -rf $file0 $file1 $xattr0 $xattr1
10744
10745         return 0
10746 }
10747 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10748
10749 test_102p() { # LU-4703 setxattr did not check ownership
10750         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10751                 skip "MDS needs to be at least 2.5.56"
10752
10753         local testfile=$DIR/$tfile
10754
10755         touch $testfile
10756
10757         echo "setfacl as user..."
10758         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10759         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10760
10761         echo "setfattr as user..."
10762         setfacl -m "u:$RUNAS_ID:---" $testfile
10763         $RUNAS setfattr -x system.posix_acl_access $testfile
10764         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10765 }
10766 run_test 102p "check setxattr(2) correctly fails without permission"
10767
10768 test_102q() {
10769         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10770                 skip "MDS needs to be at least 2.6.92"
10771
10772         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10773 }
10774 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10775
10776 test_102r() {
10777         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10778                 skip "MDS needs to be at least 2.6.93"
10779
10780         touch $DIR/$tfile || error "touch"
10781         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10782         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10783         rm $DIR/$tfile || error "rm"
10784
10785         #normal directory
10786         mkdir -p $DIR/$tdir || error "mkdir"
10787         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10788         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10789         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10790                 error "$testfile error deleting user.author1"
10791         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10792                 grep "user.$(basename $tdir)" &&
10793                 error "$tdir did not delete user.$(basename $tdir)"
10794         rmdir $DIR/$tdir || error "rmdir"
10795
10796         #striped directory
10797         test_mkdir $DIR/$tdir
10798         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10799         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10800         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10801                 error "$testfile error deleting user.author1"
10802         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10803                 grep "user.$(basename $tdir)" &&
10804                 error "$tdir did not delete user.$(basename $tdir)"
10805         rmdir $DIR/$tdir || error "rm striped dir"
10806 }
10807 run_test 102r "set EAs with empty values"
10808
10809 test_102s() {
10810         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10811                 skip "MDS needs to be at least 2.11.52"
10812
10813         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10814
10815         save_lustre_params client "llite.*.xattr_cache" > $save
10816
10817         for cache in 0 1; do
10818                 lctl set_param llite.*.xattr_cache=$cache
10819
10820                 rm -f $DIR/$tfile
10821                 touch $DIR/$tfile || error "touch"
10822                 for prefix in lustre security system trusted user; do
10823                         # Note getxattr() may fail with 'Operation not
10824                         # supported' or 'No such attribute' depending
10825                         # on prefix and cache.
10826                         getfattr -n $prefix.n102s $DIR/$tfile &&
10827                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10828                 done
10829         done
10830
10831         restore_lustre_params < $save
10832 }
10833 run_test 102s "getting nonexistent xattrs should fail"
10834
10835 test_102t() {
10836         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10837                 skip "MDS needs to be at least 2.11.52"
10838
10839         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10840
10841         save_lustre_params client "llite.*.xattr_cache" > $save
10842
10843         for cache in 0 1; do
10844                 lctl set_param llite.*.xattr_cache=$cache
10845
10846                 for buf_size in 0 256; do
10847                         rm -f $DIR/$tfile
10848                         touch $DIR/$tfile || error "touch"
10849                         setfattr -n user.multiop $DIR/$tfile
10850                         $MULTIOP $DIR/$tfile oa$buf_size ||
10851                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10852                 done
10853         done
10854
10855         restore_lustre_params < $save
10856 }
10857 run_test 102t "zero length xattr values handled correctly"
10858
10859 run_acl_subtest()
10860 {
10861     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10862     return $?
10863 }
10864
10865 test_103a() {
10866         [ "$UID" != 0 ] && skip "must run as root"
10867         $GSS && skip_env "could not run under gss"
10868         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10869                 skip_env "must have acl enabled"
10870         [ -z "$(which setfacl 2>/dev/null)" ] &&
10871                 skip_env "could not find setfacl"
10872         remote_mds_nodsh && skip "remote MDS with nodsh"
10873
10874         gpasswd -a daemon bin                           # LU-5641
10875         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10876
10877         declare -a identity_old
10878
10879         for num in $(seq $MDSCOUNT); do
10880                 switch_identity $num true || identity_old[$num]=$?
10881         done
10882
10883         SAVE_UMASK=$(umask)
10884         umask 0022
10885         mkdir -p $DIR/$tdir
10886         cd $DIR/$tdir
10887
10888         echo "performing cp ..."
10889         run_acl_subtest cp || error "run_acl_subtest cp failed"
10890         echo "performing getfacl-noacl..."
10891         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10892         echo "performing misc..."
10893         run_acl_subtest misc || error  "misc test failed"
10894         echo "performing permissions..."
10895         run_acl_subtest permissions || error "permissions failed"
10896         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10897         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10898                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10899                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10900         then
10901                 echo "performing permissions xattr..."
10902                 run_acl_subtest permissions_xattr ||
10903                         error "permissions_xattr failed"
10904         fi
10905         echo "performing setfacl..."
10906         run_acl_subtest setfacl || error  "setfacl test failed"
10907
10908         # inheritance test got from HP
10909         echo "performing inheritance..."
10910         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10911         chmod +x make-tree || error "chmod +x failed"
10912         run_acl_subtest inheritance || error "inheritance test failed"
10913         rm -f make-tree
10914
10915         echo "LU-974 ignore umask when acl is enabled..."
10916         run_acl_subtest 974 || error "LU-974 umask test failed"
10917         if [ $MDSCOUNT -ge 2 ]; then
10918                 run_acl_subtest 974_remote ||
10919                         error "LU-974 umask test failed under remote dir"
10920         fi
10921
10922         echo "LU-2561 newly created file is same size as directory..."
10923         if [ "$mds1_FSTYPE" != "zfs" ]; then
10924                 run_acl_subtest 2561 || error "LU-2561 test failed"
10925         else
10926                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10927         fi
10928
10929         run_acl_subtest 4924 || error "LU-4924 test failed"
10930
10931         cd $SAVE_PWD
10932         umask $SAVE_UMASK
10933
10934         for num in $(seq $MDSCOUNT); do
10935                 if [ "${identity_old[$num]}" = 1 ]; then
10936                         switch_identity $num false || identity_old[$num]=$?
10937                 fi
10938         done
10939 }
10940 run_test 103a "acl test"
10941
10942 test_103b() {
10943         declare -a pids
10944         local U
10945
10946         for U in {0..511}; do
10947                 {
10948                 local O=$(printf "%04o" $U)
10949
10950                 umask $(printf "%04o" $((511 ^ $O)))
10951                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10952                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10953
10954                 (( $S == ($O & 0666) )) ||
10955                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10956
10957                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10958                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10959                 (( $S == ($O & 0666) )) ||
10960                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10961
10962                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10963                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10964                 (( $S == ($O & 0666) )) ||
10965                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10966                 rm -f $DIR/$tfile.[smp]$0
10967                 } &
10968                 local pid=$!
10969
10970                 # limit the concurrently running threads to 64. LU-11878
10971                 local idx=$((U % 64))
10972                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10973                 pids[idx]=$pid
10974         done
10975         wait
10976 }
10977 run_test 103b "umask lfs setstripe"
10978
10979 test_103c() {
10980         mkdir -p $DIR/$tdir
10981         cp -rp $DIR/$tdir $DIR/$tdir.bak
10982
10983         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10984                 error "$DIR/$tdir shouldn't contain default ACL"
10985         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10986                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10987         true
10988 }
10989 run_test 103c "'cp -rp' won't set empty acl"
10990
10991 test_103e() {
10992         local numacl
10993         local fileacl
10994         local saved_debug=$($LCTL get_param -n debug)
10995
10996         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10997                 skip "MDS needs to be at least 2.14.0"
10998
10999         large_xattr_enabled || skip_env "ea_inode feature disabled"
11000
11001         mkdir -p $DIR/$tdir
11002         # add big LOV EA to cause reply buffer overflow earlier
11003         $LFS setstripe -C 1000 $DIR/$tdir
11004         lctl set_param mdc.*-mdc*.stats=clear
11005
11006         $LCTL set_param debug=0
11007         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11008         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11009
11010         # add a large number of default ACLs (expect 8000+ for 2.13+)
11011         for U in {2..7000}; do
11012                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11013                         error "Able to add just $U default ACLs"
11014         done
11015         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11016         echo "$numacl default ACLs created"
11017
11018         stat $DIR/$tdir || error "Cannot stat directory"
11019         # check file creation
11020         touch $DIR/$tdir/$tfile ||
11021                 error "failed to create $tfile with $numacl default ACLs"
11022         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11023         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11024         echo "$fileacl ACLs were inherited"
11025         (( $fileacl == $numacl )) ||
11026                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11027         # check that new ACLs creation adds new ACLs to inherited ACLs
11028         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11029                 error "Cannot set new ACL"
11030         numacl=$((numacl + 1))
11031         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11032         (( $fileacl == $numacl )) ||
11033                 error "failed to add new ACL: $fileacl != $numacl as expected"
11034         # adds more ACLs to a file to reach their maximum at 8000+
11035         numacl=0
11036         for U in {20000..25000}; do
11037                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11038                 numacl=$((numacl + 1))
11039         done
11040         echo "Added $numacl more ACLs to the file"
11041         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11042         echo "Total $fileacl ACLs in file"
11043         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11044         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11045         rmdir $DIR/$tdir || error "Cannot remove directory"
11046 }
11047 run_test 103e "inheritance of big amount of default ACLs"
11048
11049 test_103f() {
11050         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11051                 skip "MDS needs to be at least 2.14.51"
11052
11053         large_xattr_enabled || skip_env "ea_inode feature disabled"
11054
11055         # enable changelog to consume more internal MDD buffers
11056         changelog_register
11057
11058         mkdir -p $DIR/$tdir
11059         # add big LOV EA
11060         $LFS setstripe -C 1000 $DIR/$tdir
11061         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11062         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11063         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11064         rmdir $DIR/$tdir || error "Cannot remove directory"
11065 }
11066 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11067
11068 test_104a() {
11069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11070
11071         touch $DIR/$tfile
11072         lfs df || error "lfs df failed"
11073         lfs df -ih || error "lfs df -ih failed"
11074         lfs df -h $DIR || error "lfs df -h $DIR failed"
11075         lfs df -i $DIR || error "lfs df -i $DIR failed"
11076         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11077         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11078
11079         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11080         lctl --device %$OSC deactivate
11081         lfs df || error "lfs df with deactivated OSC failed"
11082         lctl --device %$OSC activate
11083         # wait the osc back to normal
11084         wait_osc_import_ready client ost
11085
11086         lfs df || error "lfs df with reactivated OSC failed"
11087         rm -f $DIR/$tfile
11088 }
11089 run_test 104a "lfs df [-ih] [path] test ========================="
11090
11091 test_104b() {
11092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11093         [ $RUNAS_ID -eq $UID ] &&
11094                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11095
11096         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11097                         grep "Permission denied" | wc -l)))
11098         if [ $denied_cnt -ne 0 ]; then
11099                 error "lfs check servers test failed"
11100         fi
11101 }
11102 run_test 104b "$RUNAS lfs check servers test ===================="
11103
11104 #
11105 # Verify $1 is within range of $2.
11106 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11107 # $1 is <= 2% of $2. Else Fail.
11108 #
11109 value_in_range() {
11110         # Strip all units (M, G, T)
11111         actual=$(echo $1 | tr -d A-Z)
11112         expect=$(echo $2 | tr -d A-Z)
11113
11114         expect_lo=$(($expect * 98 / 100)) # 2% below
11115         expect_hi=$(($expect * 102 / 100)) # 2% above
11116
11117         # permit 2% drift above and below
11118         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11119 }
11120
11121 test_104c() {
11122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11123         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11124
11125         local ost_param="osd-zfs.$FSNAME-OST0000."
11126         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11127         local ofacets=$(get_facets OST)
11128         local mfacets=$(get_facets MDS)
11129         local saved_ost_blocks=
11130         local saved_mdt_blocks=
11131
11132         echo "Before recordsize change"
11133         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11134         df=($(df -h | grep "/mnt/lustre"$))
11135
11136         # For checking.
11137         echo "lfs output : ${lfs_df[*]}"
11138         echo "df  output : ${df[*]}"
11139
11140         for facet in ${ofacets//,/ }; do
11141                 if [ -z $saved_ost_blocks ]; then
11142                         saved_ost_blocks=$(do_facet $facet \
11143                                 lctl get_param -n $ost_param.blocksize)
11144                         echo "OST Blocksize: $saved_ost_blocks"
11145                 fi
11146                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11147                 do_facet $facet zfs set recordsize=32768 $ost
11148         done
11149
11150         # BS too small. Sufficient for functional testing.
11151         for facet in ${mfacets//,/ }; do
11152                 if [ -z $saved_mdt_blocks ]; then
11153                         saved_mdt_blocks=$(do_facet $facet \
11154                                 lctl get_param -n $mdt_param.blocksize)
11155                         echo "MDT Blocksize: $saved_mdt_blocks"
11156                 fi
11157                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11158                 do_facet $facet zfs set recordsize=32768 $mdt
11159         done
11160
11161         # Give new values chance to reflect change
11162         sleep 2
11163
11164         echo "After recordsize change"
11165         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11166         df_after=($(df -h | grep "/mnt/lustre"$))
11167
11168         # For checking.
11169         echo "lfs output : ${lfs_df_after[*]}"
11170         echo "df  output : ${df_after[*]}"
11171
11172         # Verify lfs df
11173         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11174                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11175         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11176                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11177         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11178                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11179
11180         # Verify df
11181         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11182                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11183         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11184                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11185         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11186                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11187
11188         # Restore MDT recordize back to original
11189         for facet in ${mfacets//,/ }; do
11190                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11191                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11192         done
11193
11194         # Restore OST recordize back to original
11195         for facet in ${ofacets//,/ }; do
11196                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11197                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11198         done
11199
11200         return 0
11201 }
11202 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11203
11204 test_105a() {
11205         # doesn't work on 2.4 kernels
11206         touch $DIR/$tfile
11207         if $(flock_is_enabled); then
11208                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11209         else
11210                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11211         fi
11212         rm -f $DIR/$tfile
11213 }
11214 run_test 105a "flock when mounted without -o flock test ========"
11215
11216 test_105b() {
11217         touch $DIR/$tfile
11218         if $(flock_is_enabled); then
11219                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11220         else
11221                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11222         fi
11223         rm -f $DIR/$tfile
11224 }
11225 run_test 105b "fcntl when mounted without -o flock test ========"
11226
11227 test_105c() {
11228         touch $DIR/$tfile
11229         if $(flock_is_enabled); then
11230                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11231         else
11232                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11233         fi
11234         rm -f $DIR/$tfile
11235 }
11236 run_test 105c "lockf when mounted without -o flock test"
11237
11238 test_105d() { # bug 15924
11239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11240
11241         test_mkdir $DIR/$tdir
11242         flock_is_enabled || skip_env "mount w/o flock enabled"
11243         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11244         $LCTL set_param fail_loc=0x80000315
11245         flocks_test 2 $DIR/$tdir
11246 }
11247 run_test 105d "flock race (should not freeze) ========"
11248
11249 test_105e() { # bug 22660 && 22040
11250         flock_is_enabled || skip_env "mount w/o flock enabled"
11251
11252         touch $DIR/$tfile
11253         flocks_test 3 $DIR/$tfile
11254 }
11255 run_test 105e "Two conflicting flocks from same process"
11256
11257 test_106() { #bug 10921
11258         test_mkdir $DIR/$tdir
11259         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11260         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11261 }
11262 run_test 106 "attempt exec of dir followed by chown of that dir"
11263
11264 test_107() {
11265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11266
11267         CDIR=`pwd`
11268         local file=core
11269
11270         cd $DIR
11271         rm -f $file
11272
11273         local save_pattern=$(sysctl -n kernel.core_pattern)
11274         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11275         sysctl -w kernel.core_pattern=$file
11276         sysctl -w kernel.core_uses_pid=0
11277
11278         ulimit -c unlimited
11279         sleep 60 &
11280         SLEEPPID=$!
11281
11282         sleep 1
11283
11284         kill -s 11 $SLEEPPID
11285         wait $SLEEPPID
11286         if [ -e $file ]; then
11287                 size=`stat -c%s $file`
11288                 [ $size -eq 0 ] && error "Fail to create core file $file"
11289         else
11290                 error "Fail to create core file $file"
11291         fi
11292         rm -f $file
11293         sysctl -w kernel.core_pattern=$save_pattern
11294         sysctl -w kernel.core_uses_pid=$save_uses_pid
11295         cd $CDIR
11296 }
11297 run_test 107 "Coredump on SIG"
11298
11299 test_110() {
11300         test_mkdir $DIR/$tdir
11301         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11302         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11303                 error "mkdir with 256 char should fail, but did not"
11304         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11305                 error "create with 255 char failed"
11306         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11307                 error "create with 256 char should fail, but did not"
11308
11309         ls -l $DIR/$tdir
11310         rm -rf $DIR/$tdir
11311 }
11312 run_test 110 "filename length checking"
11313
11314 #
11315 # Purpose: To verify dynamic thread (OSS) creation.
11316 #
11317 test_115() {
11318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11319         remote_ost_nodsh && skip "remote OST with nodsh"
11320
11321         # Lustre does not stop service threads once they are started.
11322         # Reset number of running threads to default.
11323         stopall
11324         setupall
11325
11326         local OSTIO_pre
11327         local save_params="$TMP/sanity-$TESTNAME.parameters"
11328
11329         # Get ll_ost_io count before I/O
11330         OSTIO_pre=$(do_facet ost1 \
11331                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11332         # Exit if lustre is not running (ll_ost_io not running).
11333         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11334
11335         echo "Starting with $OSTIO_pre threads"
11336         local thread_max=$((OSTIO_pre * 2))
11337         local rpc_in_flight=$((thread_max * 2))
11338         # Number of I/O Process proposed to be started.
11339         local nfiles
11340         local facets=$(get_facets OST)
11341
11342         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11343         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11344
11345         # Set in_flight to $rpc_in_flight
11346         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11347                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11348         nfiles=${rpc_in_flight}
11349         # Set ost thread_max to $thread_max
11350         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11351
11352         # 5 Minutes should be sufficient for max number of OSS
11353         # threads(thread_max) to be created.
11354         local timeout=300
11355
11356         # Start I/O.
11357         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11358         test_mkdir $DIR/$tdir
11359         for i in $(seq $nfiles); do
11360                 local file=$DIR/$tdir/${tfile}-$i
11361                 $LFS setstripe -c -1 -i 0 $file
11362                 ($WTL $file $timeout)&
11363         done
11364
11365         # I/O Started - Wait for thread_started to reach thread_max or report
11366         # error if thread_started is more than thread_max.
11367         echo "Waiting for thread_started to reach thread_max"
11368         local thread_started=0
11369         local end_time=$((SECONDS + timeout))
11370
11371         while [ $SECONDS -le $end_time ] ; do
11372                 echo -n "."
11373                 # Get ost i/o thread_started count.
11374                 thread_started=$(do_facet ost1 \
11375                         "$LCTL get_param \
11376                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11377                 # Break out if thread_started is equal/greater than thread_max
11378                 if [[ $thread_started -ge $thread_max ]]; then
11379                         echo ll_ost_io thread_started $thread_started, \
11380                                 equal/greater than thread_max $thread_max
11381                         break
11382                 fi
11383                 sleep 1
11384         done
11385
11386         # Cleanup - We have the numbers, Kill i/o jobs if running.
11387         jobcount=($(jobs -p))
11388         for i in $(seq 0 $((${#jobcount[@]}-1)))
11389         do
11390                 kill -9 ${jobcount[$i]}
11391                 if [ $? -ne 0 ] ; then
11392                         echo Warning: \
11393                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11394                 fi
11395         done
11396
11397         # Cleanup files left by WTL binary.
11398         for i in $(seq $nfiles); do
11399                 local file=$DIR/$tdir/${tfile}-$i
11400                 rm -rf $file
11401                 if [ $? -ne 0 ] ; then
11402                         echo "Warning: Failed to delete file $file"
11403                 fi
11404         done
11405
11406         restore_lustre_params <$save_params
11407         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11408
11409         # Error out if no new thread has started or Thread started is greater
11410         # than thread max.
11411         if [[ $thread_started -le $OSTIO_pre ||
11412                         $thread_started -gt $thread_max ]]; then
11413                 error "ll_ost_io: thread_started $thread_started" \
11414                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11415                       "No new thread started or thread started greater " \
11416                       "than thread_max."
11417         fi
11418 }
11419 run_test 115 "verify dynamic thread creation===================="
11420
11421 free_min_max () {
11422         wait_delete_completed
11423         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11424         echo "OST kbytes available: ${AVAIL[@]}"
11425         MAXV=${AVAIL[0]}
11426         MAXI=0
11427         MINV=${AVAIL[0]}
11428         MINI=0
11429         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11430                 #echo OST $i: ${AVAIL[i]}kb
11431                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11432                         MAXV=${AVAIL[i]}
11433                         MAXI=$i
11434                 fi
11435                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11436                         MINV=${AVAIL[i]}
11437                         MINI=$i
11438                 fi
11439         done
11440         echo "Min free space: OST $MINI: $MINV"
11441         echo "Max free space: OST $MAXI: $MAXV"
11442 }
11443
11444 test_116a() { # was previously test_116()
11445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11446         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11447         remote_mds_nodsh && skip "remote MDS with nodsh"
11448
11449         echo -n "Free space priority "
11450         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11451                 head -n1
11452         declare -a AVAIL
11453         free_min_max
11454
11455         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11456         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11457         trap simple_cleanup_common EXIT
11458
11459         # Check if we need to generate uneven OSTs
11460         test_mkdir -p $DIR/$tdir/OST${MINI}
11461         local FILL=$((MINV / 4))
11462         local DIFF=$((MAXV - MINV))
11463         local DIFF2=$((DIFF * 100 / MINV))
11464
11465         local threshold=$(do_facet $SINGLEMDS \
11466                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11467         threshold=${threshold%%%}
11468         echo -n "Check for uneven OSTs: "
11469         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11470
11471         if [[ $DIFF2 -gt $threshold ]]; then
11472                 echo "ok"
11473                 echo "Don't need to fill OST$MINI"
11474         else
11475                 # generate uneven OSTs. Write 2% over the QOS threshold value
11476                 echo "no"
11477                 DIFF=$((threshold - DIFF2 + 2))
11478                 DIFF2=$((MINV * DIFF / 100))
11479                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11480                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11481                         error "setstripe failed"
11482                 DIFF=$((DIFF2 / 2048))
11483                 i=0
11484                 while [ $i -lt $DIFF ]; do
11485                         i=$((i + 1))
11486                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11487                                 bs=2M count=1 2>/dev/null
11488                         echo -n .
11489                 done
11490                 echo .
11491                 sync
11492                 sleep_maxage
11493                 free_min_max
11494         fi
11495
11496         DIFF=$((MAXV - MINV))
11497         DIFF2=$((DIFF * 100 / MINV))
11498         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11499         if [ $DIFF2 -gt $threshold ]; then
11500                 echo "ok"
11501         else
11502                 echo "failed - QOS mode won't be used"
11503                 simple_cleanup_common
11504                 skip "QOS imbalance criteria not met"
11505         fi
11506
11507         MINI1=$MINI
11508         MINV1=$MINV
11509         MAXI1=$MAXI
11510         MAXV1=$MAXV
11511
11512         # now fill using QOS
11513         $LFS setstripe -c 1 $DIR/$tdir
11514         FILL=$((FILL / 200))
11515         if [ $FILL -gt 600 ]; then
11516                 FILL=600
11517         fi
11518         echo "writing $FILL files to QOS-assigned OSTs"
11519         i=0
11520         while [ $i -lt $FILL ]; do
11521                 i=$((i + 1))
11522                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11523                         count=1 2>/dev/null
11524                 echo -n .
11525         done
11526         echo "wrote $i 200k files"
11527         sync
11528         sleep_maxage
11529
11530         echo "Note: free space may not be updated, so measurements might be off"
11531         free_min_max
11532         DIFF2=$((MAXV - MINV))
11533         echo "free space delta: orig $DIFF final $DIFF2"
11534         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11535         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11536         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11537         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11538         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11539         if [[ $DIFF -gt 0 ]]; then
11540                 FILL=$((DIFF2 * 100 / DIFF - 100))
11541                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11542         fi
11543
11544         # Figure out which files were written where
11545         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11546                awk '/'$MINI1': / {print $2; exit}')
11547         echo $UUID
11548         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11549         echo "$MINC files created on smaller OST $MINI1"
11550         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11551                awk '/'$MAXI1': / {print $2; exit}')
11552         echo $UUID
11553         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11554         echo "$MAXC files created on larger OST $MAXI1"
11555         if [[ $MINC -gt 0 ]]; then
11556                 FILL=$((MAXC * 100 / MINC - 100))
11557                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11558         fi
11559         [[ $MAXC -gt $MINC ]] ||
11560                 error_ignore LU-9 "stripe QOS didn't balance free space"
11561         simple_cleanup_common
11562 }
11563 run_test 116a "stripe QOS: free space balance ==================="
11564
11565 test_116b() { # LU-2093
11566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11567         remote_mds_nodsh && skip "remote MDS with nodsh"
11568
11569 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11570         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11571                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11572         [ -z "$old_rr" ] && skip "no QOS"
11573         do_facet $SINGLEMDS lctl set_param \
11574                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11575         mkdir -p $DIR/$tdir
11576         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11577         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11578         do_facet $SINGLEMDS lctl set_param fail_loc=0
11579         rm -rf $DIR/$tdir
11580         do_facet $SINGLEMDS lctl set_param \
11581                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11582 }
11583 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11584
11585 test_117() # bug 10891
11586 {
11587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11588
11589         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11590         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11591         lctl set_param fail_loc=0x21e
11592         > $DIR/$tfile || error "truncate failed"
11593         lctl set_param fail_loc=0
11594         echo "Truncate succeeded."
11595         rm -f $DIR/$tfile
11596 }
11597 run_test 117 "verify osd extend =========="
11598
11599 NO_SLOW_RESENDCOUNT=4
11600 export OLD_RESENDCOUNT=""
11601 set_resend_count () {
11602         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11603         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11604         lctl set_param -n $PROC_RESENDCOUNT $1
11605         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11606 }
11607
11608 # for reduce test_118* time (b=14842)
11609 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11610
11611 # Reset async IO behavior after error case
11612 reset_async() {
11613         FILE=$DIR/reset_async
11614
11615         # Ensure all OSCs are cleared
11616         $LFS setstripe -c -1 $FILE
11617         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11618         sync
11619         rm $FILE
11620 }
11621
11622 test_118a() #bug 11710
11623 {
11624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11625
11626         reset_async
11627
11628         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11629         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11630         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11631
11632         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11633                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11634                 return 1;
11635         fi
11636         rm -f $DIR/$tfile
11637 }
11638 run_test 118a "verify O_SYNC works =========="
11639
11640 test_118b()
11641 {
11642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11643         remote_ost_nodsh && skip "remote OST with nodsh"
11644
11645         reset_async
11646
11647         #define OBD_FAIL_SRV_ENOENT 0x217
11648         set_nodes_failloc "$(osts_nodes)" 0x217
11649         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11650         RC=$?
11651         set_nodes_failloc "$(osts_nodes)" 0
11652         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11653         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11654                     grep -c writeback)
11655
11656         if [[ $RC -eq 0 ]]; then
11657                 error "Must return error due to dropped pages, rc=$RC"
11658                 return 1;
11659         fi
11660
11661         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11662                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11663                 return 1;
11664         fi
11665
11666         echo "Dirty pages not leaked on ENOENT"
11667
11668         # Due to the above error the OSC will issue all RPCs syncronously
11669         # until a subsequent RPC completes successfully without error.
11670         $MULTIOP $DIR/$tfile Ow4096yc
11671         rm -f $DIR/$tfile
11672
11673         return 0
11674 }
11675 run_test 118b "Reclaim dirty pages on fatal error =========="
11676
11677 test_118c()
11678 {
11679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11680
11681         # for 118c, restore the original resend count, LU-1940
11682         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11683                                 set_resend_count $OLD_RESENDCOUNT
11684         remote_ost_nodsh && skip "remote OST with nodsh"
11685
11686         reset_async
11687
11688         #define OBD_FAIL_OST_EROFS               0x216
11689         set_nodes_failloc "$(osts_nodes)" 0x216
11690
11691         # multiop should block due to fsync until pages are written
11692         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11693         MULTIPID=$!
11694         sleep 1
11695
11696         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11697                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11698         fi
11699
11700         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11701                     grep -c writeback)
11702         if [[ $WRITEBACK -eq 0 ]]; then
11703                 error "No page in writeback, writeback=$WRITEBACK"
11704         fi
11705
11706         set_nodes_failloc "$(osts_nodes)" 0
11707         wait $MULTIPID
11708         RC=$?
11709         if [[ $RC -ne 0 ]]; then
11710                 error "Multiop fsync failed, rc=$RC"
11711         fi
11712
11713         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11714         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11715                     grep -c writeback)
11716         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11717                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11718         fi
11719
11720         rm -f $DIR/$tfile
11721         echo "Dirty pages flushed via fsync on EROFS"
11722         return 0
11723 }
11724 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11725
11726 # continue to use small resend count to reduce test_118* time (b=14842)
11727 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11728
11729 test_118d()
11730 {
11731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11732         remote_ost_nodsh && skip "remote OST with nodsh"
11733
11734         reset_async
11735
11736         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11737         set_nodes_failloc "$(osts_nodes)" 0x214
11738         # multiop should block due to fsync until pages are written
11739         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11740         MULTIPID=$!
11741         sleep 1
11742
11743         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11744                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11745         fi
11746
11747         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11748                     grep -c writeback)
11749         if [[ $WRITEBACK -eq 0 ]]; then
11750                 error "No page in writeback, writeback=$WRITEBACK"
11751         fi
11752
11753         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11754         set_nodes_failloc "$(osts_nodes)" 0
11755
11756         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11757         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11758                     grep -c writeback)
11759         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11760                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11761         fi
11762
11763         rm -f $DIR/$tfile
11764         echo "Dirty pages gaurenteed flushed via fsync"
11765         return 0
11766 }
11767 run_test 118d "Fsync validation inject a delay of the bulk =========="
11768
11769 test_118f() {
11770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11771
11772         reset_async
11773
11774         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11775         lctl set_param fail_loc=0x8000040a
11776
11777         # Should simulate EINVAL error which is fatal
11778         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11779         RC=$?
11780         if [[ $RC -eq 0 ]]; then
11781                 error "Must return error due to dropped pages, rc=$RC"
11782         fi
11783
11784         lctl set_param fail_loc=0x0
11785
11786         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11787         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11788         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11789                     grep -c writeback)
11790         if [[ $LOCKED -ne 0 ]]; then
11791                 error "Locked pages remain in cache, locked=$LOCKED"
11792         fi
11793
11794         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11795                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11796         fi
11797
11798         rm -f $DIR/$tfile
11799         echo "No pages locked after fsync"
11800
11801         reset_async
11802         return 0
11803 }
11804 run_test 118f "Simulate unrecoverable OSC side error =========="
11805
11806 test_118g() {
11807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11808
11809         reset_async
11810
11811         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11812         lctl set_param fail_loc=0x406
11813
11814         # simulate local -ENOMEM
11815         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11816         RC=$?
11817
11818         lctl set_param fail_loc=0
11819         if [[ $RC -eq 0 ]]; then
11820                 error "Must return error due to dropped pages, rc=$RC"
11821         fi
11822
11823         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11824         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11825         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11826                         grep -c writeback)
11827         if [[ $LOCKED -ne 0 ]]; then
11828                 error "Locked pages remain in cache, locked=$LOCKED"
11829         fi
11830
11831         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11832                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11833         fi
11834
11835         rm -f $DIR/$tfile
11836         echo "No pages locked after fsync"
11837
11838         reset_async
11839         return 0
11840 }
11841 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11842
11843 test_118h() {
11844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11845         remote_ost_nodsh && skip "remote OST with nodsh"
11846
11847         reset_async
11848
11849         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11850         set_nodes_failloc "$(osts_nodes)" 0x20e
11851         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11852         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11853         RC=$?
11854
11855         set_nodes_failloc "$(osts_nodes)" 0
11856         if [[ $RC -eq 0 ]]; then
11857                 error "Must return error due to dropped pages, rc=$RC"
11858         fi
11859
11860         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11861         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11862         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11863                     grep -c writeback)
11864         if [[ $LOCKED -ne 0 ]]; then
11865                 error "Locked pages remain in cache, locked=$LOCKED"
11866         fi
11867
11868         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11869                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11870         fi
11871
11872         rm -f $DIR/$tfile
11873         echo "No pages locked after fsync"
11874
11875         return 0
11876 }
11877 run_test 118h "Verify timeout in handling recoverables errors  =========="
11878
11879 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11880
11881 test_118i() {
11882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11883         remote_ost_nodsh && skip "remote OST with nodsh"
11884
11885         reset_async
11886
11887         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11888         set_nodes_failloc "$(osts_nodes)" 0x20e
11889
11890         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11891         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11892         PID=$!
11893         sleep 5
11894         set_nodes_failloc "$(osts_nodes)" 0
11895
11896         wait $PID
11897         RC=$?
11898         if [[ $RC -ne 0 ]]; then
11899                 error "got error, but should be not, rc=$RC"
11900         fi
11901
11902         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11903         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11904         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11905         if [[ $LOCKED -ne 0 ]]; then
11906                 error "Locked pages remain in cache, locked=$LOCKED"
11907         fi
11908
11909         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11910                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11911         fi
11912
11913         rm -f $DIR/$tfile
11914         echo "No pages locked after fsync"
11915
11916         return 0
11917 }
11918 run_test 118i "Fix error before timeout in recoverable error  =========="
11919
11920 [ "$SLOW" = "no" ] && set_resend_count 4
11921
11922 test_118j() {
11923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11924         remote_ost_nodsh && skip "remote OST with nodsh"
11925
11926         reset_async
11927
11928         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11929         set_nodes_failloc "$(osts_nodes)" 0x220
11930
11931         # return -EIO from OST
11932         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11933         RC=$?
11934         set_nodes_failloc "$(osts_nodes)" 0x0
11935         if [[ $RC -eq 0 ]]; then
11936                 error "Must return error due to dropped pages, rc=$RC"
11937         fi
11938
11939         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11940         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11941         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11942         if [[ $LOCKED -ne 0 ]]; then
11943                 error "Locked pages remain in cache, locked=$LOCKED"
11944         fi
11945
11946         # in recoverable error on OST we want resend and stay until it finished
11947         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11948                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11949         fi
11950
11951         rm -f $DIR/$tfile
11952         echo "No pages locked after fsync"
11953
11954         return 0
11955 }
11956 run_test 118j "Simulate unrecoverable OST side error =========="
11957
11958 test_118k()
11959 {
11960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11961         remote_ost_nodsh && skip "remote OSTs with nodsh"
11962
11963         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11964         set_nodes_failloc "$(osts_nodes)" 0x20e
11965         test_mkdir $DIR/$tdir
11966
11967         for ((i=0;i<10;i++)); do
11968                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11969                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11970                 SLEEPPID=$!
11971                 sleep 0.500s
11972                 kill $SLEEPPID
11973                 wait $SLEEPPID
11974         done
11975
11976         set_nodes_failloc "$(osts_nodes)" 0
11977         rm -rf $DIR/$tdir
11978 }
11979 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11980
11981 test_118l() # LU-646
11982 {
11983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11984
11985         test_mkdir $DIR/$tdir
11986         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11987         rm -rf $DIR/$tdir
11988 }
11989 run_test 118l "fsync dir"
11990
11991 test_118m() # LU-3066
11992 {
11993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11994
11995         test_mkdir $DIR/$tdir
11996         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11997         rm -rf $DIR/$tdir
11998 }
11999 run_test 118m "fdatasync dir ========="
12000
12001 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12002
12003 test_118n()
12004 {
12005         local begin
12006         local end
12007
12008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12009         remote_ost_nodsh && skip "remote OSTs with nodsh"
12010
12011         # Sleep to avoid a cached response.
12012         #define OBD_STATFS_CACHE_SECONDS 1
12013         sleep 2
12014
12015         # Inject a 10 second delay in the OST_STATFS handler.
12016         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12017         set_nodes_failloc "$(osts_nodes)" 0x242
12018
12019         begin=$SECONDS
12020         stat --file-system $MOUNT > /dev/null
12021         end=$SECONDS
12022
12023         set_nodes_failloc "$(osts_nodes)" 0
12024
12025         if ((end - begin > 20)); then
12026             error "statfs took $((end - begin)) seconds, expected 10"
12027         fi
12028 }
12029 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12030
12031 test_119a() # bug 11737
12032 {
12033         BSIZE=$((512 * 1024))
12034         directio write $DIR/$tfile 0 1 $BSIZE
12035         # We ask to read two blocks, which is more than a file size.
12036         # directio will indicate an error when requested and actual
12037         # sizes aren't equeal (a normal situation in this case) and
12038         # print actual read amount.
12039         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12040         if [ "$NOB" != "$BSIZE" ]; then
12041                 error "read $NOB bytes instead of $BSIZE"
12042         fi
12043         rm -f $DIR/$tfile
12044 }
12045 run_test 119a "Short directIO read must return actual read amount"
12046
12047 test_119b() # bug 11737
12048 {
12049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12050
12051         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12052         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12053         sync
12054         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12055                 error "direct read failed"
12056         rm -f $DIR/$tfile
12057 }
12058 run_test 119b "Sparse directIO read must return actual read amount"
12059
12060 test_119c() # bug 13099
12061 {
12062         BSIZE=1048576
12063         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12064         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12065         rm -f $DIR/$tfile
12066 }
12067 run_test 119c "Testing for direct read hitting hole"
12068
12069 test_119d() # bug 15950
12070 {
12071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12072
12073         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12074         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12075         BSIZE=1048576
12076         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12077         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12078         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12079         lctl set_param fail_loc=0x40d
12080         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12081         pid_dio=$!
12082         sleep 1
12083         cat $DIR/$tfile > /dev/null &
12084         lctl set_param fail_loc=0
12085         pid_reads=$!
12086         wait $pid_dio
12087         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12088         sleep 2
12089         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12090         error "the read rpcs have not completed in 2s"
12091         rm -f $DIR/$tfile
12092         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12093 }
12094 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12095
12096 test_120a() {
12097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12098         remote_mds_nodsh && skip "remote MDS with nodsh"
12099         test_mkdir -i0 -c1 $DIR/$tdir
12100         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12101                 skip_env "no early lock cancel on server"
12102
12103         lru_resize_disable mdc
12104         lru_resize_disable osc
12105         cancel_lru_locks mdc
12106         # asynchronous object destroy at MDT could cause bl ast to client
12107         cancel_lru_locks osc
12108
12109         stat $DIR/$tdir > /dev/null
12110         can1=$(do_facet mds1 \
12111                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12112                awk '/ldlm_cancel/ {print $2}')
12113         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12114                awk '/ldlm_bl_callback/ {print $2}')
12115         test_mkdir -i0 -c1 $DIR/$tdir/d1
12116         can2=$(do_facet mds1 \
12117                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12118                awk '/ldlm_cancel/ {print $2}')
12119         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12120                awk '/ldlm_bl_callback/ {print $2}')
12121         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12122         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12123         lru_resize_enable mdc
12124         lru_resize_enable osc
12125 }
12126 run_test 120a "Early Lock Cancel: mkdir test"
12127
12128 test_120b() {
12129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12130         remote_mds_nodsh && skip "remote MDS with nodsh"
12131         test_mkdir $DIR/$tdir
12132         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12133                 skip_env "no early lock cancel on server"
12134
12135         lru_resize_disable mdc
12136         lru_resize_disable osc
12137         cancel_lru_locks mdc
12138         stat $DIR/$tdir > /dev/null
12139         can1=$(do_facet $SINGLEMDS \
12140                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12141                awk '/ldlm_cancel/ {print $2}')
12142         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12143                awk '/ldlm_bl_callback/ {print $2}')
12144         touch $DIR/$tdir/f1
12145         can2=$(do_facet $SINGLEMDS \
12146                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12147                awk '/ldlm_cancel/ {print $2}')
12148         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12149                awk '/ldlm_bl_callback/ {print $2}')
12150         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12151         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12152         lru_resize_enable mdc
12153         lru_resize_enable osc
12154 }
12155 run_test 120b "Early Lock Cancel: create test"
12156
12157 test_120c() {
12158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12159         remote_mds_nodsh && skip "remote MDS with nodsh"
12160         test_mkdir -i0 -c1 $DIR/$tdir
12161         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12162                 skip "no early lock cancel on server"
12163
12164         lru_resize_disable mdc
12165         lru_resize_disable osc
12166         test_mkdir -i0 -c1 $DIR/$tdir/d1
12167         test_mkdir -i0 -c1 $DIR/$tdir/d2
12168         touch $DIR/$tdir/d1/f1
12169         cancel_lru_locks mdc
12170         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12171         can1=$(do_facet mds1 \
12172                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12173                awk '/ldlm_cancel/ {print $2}')
12174         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12175                awk '/ldlm_bl_callback/ {print $2}')
12176         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12177         can2=$(do_facet mds1 \
12178                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12179                awk '/ldlm_cancel/ {print $2}')
12180         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12181                awk '/ldlm_bl_callback/ {print $2}')
12182         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12183         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12184         lru_resize_enable mdc
12185         lru_resize_enable osc
12186 }
12187 run_test 120c "Early Lock Cancel: link test"
12188
12189 test_120d() {
12190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12191         remote_mds_nodsh && skip "remote MDS with nodsh"
12192         test_mkdir -i0 -c1 $DIR/$tdir
12193         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12194                 skip_env "no early lock cancel on server"
12195
12196         lru_resize_disable mdc
12197         lru_resize_disable osc
12198         touch $DIR/$tdir
12199         cancel_lru_locks mdc
12200         stat $DIR/$tdir > /dev/null
12201         can1=$(do_facet mds1 \
12202                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12203                awk '/ldlm_cancel/ {print $2}')
12204         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12205                awk '/ldlm_bl_callback/ {print $2}')
12206         chmod a+x $DIR/$tdir
12207         can2=$(do_facet mds1 \
12208                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12209                awk '/ldlm_cancel/ {print $2}')
12210         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12211                awk '/ldlm_bl_callback/ {print $2}')
12212         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12213         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12214         lru_resize_enable mdc
12215         lru_resize_enable osc
12216 }
12217 run_test 120d "Early Lock Cancel: setattr test"
12218
12219 test_120e() {
12220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12221         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12222                 skip_env "no early lock cancel on server"
12223         remote_mds_nodsh && skip "remote MDS with nodsh"
12224
12225         local dlmtrace_set=false
12226
12227         test_mkdir -i0 -c1 $DIR/$tdir
12228         lru_resize_disable mdc
12229         lru_resize_disable osc
12230         ! $LCTL get_param debug | grep -q dlmtrace &&
12231                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12232         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12233         cancel_lru_locks mdc
12234         cancel_lru_locks osc
12235         dd if=$DIR/$tdir/f1 of=/dev/null
12236         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12237         # XXX client can not do early lock cancel of OST lock
12238         # during unlink (LU-4206), so cancel osc lock now.
12239         sleep 2
12240         cancel_lru_locks osc
12241         can1=$(do_facet mds1 \
12242                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12243                awk '/ldlm_cancel/ {print $2}')
12244         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12245                awk '/ldlm_bl_callback/ {print $2}')
12246         unlink $DIR/$tdir/f1
12247         sleep 5
12248         can2=$(do_facet mds1 \
12249                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12250                awk '/ldlm_cancel/ {print $2}')
12251         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12252                awk '/ldlm_bl_callback/ {print $2}')
12253         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12254                 $LCTL dk $TMP/cancel.debug.txt
12255         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12256                 $LCTL dk $TMP/blocking.debug.txt
12257         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12258         lru_resize_enable mdc
12259         lru_resize_enable osc
12260 }
12261 run_test 120e "Early Lock Cancel: unlink test"
12262
12263 test_120f() {
12264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12265         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12266                 skip_env "no early lock cancel on server"
12267         remote_mds_nodsh && skip "remote MDS with nodsh"
12268
12269         test_mkdir -i0 -c1 $DIR/$tdir
12270         lru_resize_disable mdc
12271         lru_resize_disable osc
12272         test_mkdir -i0 -c1 $DIR/$tdir/d1
12273         test_mkdir -i0 -c1 $DIR/$tdir/d2
12274         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12275         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12276         cancel_lru_locks mdc
12277         cancel_lru_locks osc
12278         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12279         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12280         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12281         # XXX client can not do early lock cancel of OST lock
12282         # during rename (LU-4206), so cancel osc lock now.
12283         sleep 2
12284         cancel_lru_locks osc
12285         can1=$(do_facet mds1 \
12286                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12287                awk '/ldlm_cancel/ {print $2}')
12288         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12289                awk '/ldlm_bl_callback/ {print $2}')
12290         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12291         sleep 5
12292         can2=$(do_facet mds1 \
12293                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12294                awk '/ldlm_cancel/ {print $2}')
12295         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12296                awk '/ldlm_bl_callback/ {print $2}')
12297         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12298         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12299         lru_resize_enable mdc
12300         lru_resize_enable osc
12301 }
12302 run_test 120f "Early Lock Cancel: rename test"
12303
12304 test_120g() {
12305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12306         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12307                 skip_env "no early lock cancel on server"
12308         remote_mds_nodsh && skip "remote MDS with nodsh"
12309
12310         lru_resize_disable mdc
12311         lru_resize_disable osc
12312         count=10000
12313         echo create $count files
12314         test_mkdir $DIR/$tdir
12315         cancel_lru_locks mdc
12316         cancel_lru_locks osc
12317         t0=$(date +%s)
12318
12319         can0=$(do_facet $SINGLEMDS \
12320                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12321                awk '/ldlm_cancel/ {print $2}')
12322         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12323                awk '/ldlm_bl_callback/ {print $2}')
12324         createmany -o $DIR/$tdir/f $count
12325         sync
12326         can1=$(do_facet $SINGLEMDS \
12327                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12328                awk '/ldlm_cancel/ {print $2}')
12329         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12330                awk '/ldlm_bl_callback/ {print $2}')
12331         t1=$(date +%s)
12332         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12333         echo rm $count files
12334         rm -r $DIR/$tdir
12335         sync
12336         can2=$(do_facet $SINGLEMDS \
12337                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12338                awk '/ldlm_cancel/ {print $2}')
12339         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12340                awk '/ldlm_bl_callback/ {print $2}')
12341         t2=$(date +%s)
12342         echo total: $count removes in $((t2-t1))
12343         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12344         sleep 2
12345         # wait for commitment of removal
12346         lru_resize_enable mdc
12347         lru_resize_enable osc
12348 }
12349 run_test 120g "Early Lock Cancel: performance test"
12350
12351 test_121() { #bug #10589
12352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12353
12354         rm -rf $DIR/$tfile
12355         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12356 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12357         lctl set_param fail_loc=0x310
12358         cancel_lru_locks osc > /dev/null
12359         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12360         lctl set_param fail_loc=0
12361         [[ $reads -eq $writes ]] ||
12362                 error "read $reads blocks, must be $writes blocks"
12363 }
12364 run_test 121 "read cancel race ========="
12365
12366 test_123a_base() { # was test 123, statahead(bug 11401)
12367         local lsx="$1"
12368
12369         SLOWOK=0
12370         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12371                 log "testing UP system. Performance may be lower than expected."
12372                 SLOWOK=1
12373         fi
12374
12375         rm -rf $DIR/$tdir
12376         test_mkdir $DIR/$tdir
12377         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12378         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12379         MULT=10
12380         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12381                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12382
12383                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12384                 lctl set_param -n llite.*.statahead_max 0
12385                 lctl get_param llite.*.statahead_max
12386                 cancel_lru_locks mdc
12387                 cancel_lru_locks osc
12388                 stime=$(date +%s)
12389                 time $lsx $DIR/$tdir | wc -l
12390                 etime=$(date +%s)
12391                 delta=$((etime - stime))
12392                 log "$lsx $i files without statahead: $delta sec"
12393                 lctl set_param llite.*.statahead_max=$max
12394
12395                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12396                         grep "statahead wrong:" | awk '{print $3}')
12397                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12398                 cancel_lru_locks mdc
12399                 cancel_lru_locks osc
12400                 stime=$(date +%s)
12401                 time $lsx $DIR/$tdir | wc -l
12402                 etime=$(date +%s)
12403                 delta_sa=$((etime - stime))
12404                 log "$lsx $i files with statahead: $delta_sa sec"
12405                 lctl get_param -n llite.*.statahead_stats
12406                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12407                         grep "statahead wrong:" | awk '{print $3}')
12408
12409                 [[ $swrong -lt $ewrong ]] &&
12410                         log "statahead was stopped, maybe too many locks held!"
12411                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12412
12413                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12414                         max=$(lctl get_param -n llite.*.statahead_max |
12415                                 head -n 1)
12416                         lctl set_param -n llite.*.statahead_max 0
12417                         lctl get_param llite.*.statahead_max
12418                         cancel_lru_locks mdc
12419                         cancel_lru_locks osc
12420                         stime=$(date +%s)
12421                         time $lsx $DIR/$tdir | wc -l
12422                         etime=$(date +%s)
12423                         delta=$((etime - stime))
12424                         log "$lsx $i files again without statahead: $delta sec"
12425                         lctl set_param llite.*.statahead_max=$max
12426                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12427                                 if [  $SLOWOK -eq 0 ]; then
12428                                         error "$lsx $i files is slower with statahead!"
12429                                 else
12430                                         log "$lsx $i files is slower with statahead!"
12431                                 fi
12432                                 break
12433                         fi
12434                 fi
12435
12436                 [ $delta -gt 20 ] && break
12437                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12438                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12439         done
12440         log "$lsx done"
12441
12442         stime=$(date +%s)
12443         rm -r $DIR/$tdir
12444         sync
12445         etime=$(date +%s)
12446         delta=$((etime - stime))
12447         log "rm -r $DIR/$tdir/: $delta seconds"
12448         log "rm done"
12449         lctl get_param -n llite.*.statahead_stats
12450 }
12451
12452 test_123aa() {
12453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12454
12455         test_123a_base "ls -l"
12456 }
12457 run_test 123aa "verify statahead work"
12458
12459 test_123ab() {
12460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12461
12462         statx_supported || skip_env "Test must be statx() syscall supported"
12463
12464         test_123a_base "$STATX -l"
12465 }
12466 run_test 123ab "verify statahead work by using statx"
12467
12468 test_123ac() {
12469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12470
12471         statx_supported || skip_env "Test must be statx() syscall supported"
12472
12473         local rpcs_before
12474         local rpcs_after
12475         local agl_before
12476         local agl_after
12477
12478         cancel_lru_locks $OSC
12479         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12480         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12481                 awk '/agl.total:/ {print $3}')
12482         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12483         test_123a_base "$STATX --cached=always -D"
12484         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12485                 awk '/agl.total:/ {print $3}')
12486         [ $agl_before -eq $agl_after ] ||
12487                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12488         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12489         [ $rpcs_after -eq $rpcs_before ] ||
12490                 error "$STATX should not send glimpse RPCs to $OSC"
12491 }
12492 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12493
12494 test_123b () { # statahead(bug 15027)
12495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12496
12497         test_mkdir $DIR/$tdir
12498         createmany -o $DIR/$tdir/$tfile-%d 1000
12499
12500         cancel_lru_locks mdc
12501         cancel_lru_locks osc
12502
12503 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12504         lctl set_param fail_loc=0x80000803
12505         ls -lR $DIR/$tdir > /dev/null
12506         log "ls done"
12507         lctl set_param fail_loc=0x0
12508         lctl get_param -n llite.*.statahead_stats
12509         rm -r $DIR/$tdir
12510         sync
12511
12512 }
12513 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12514
12515 test_123c() {
12516         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12517
12518         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12519         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12520         touch $DIR/$tdir.1/{1..3}
12521         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12522
12523         remount_client $MOUNT
12524
12525         $MULTIOP $DIR/$tdir.0 Q
12526
12527         # let statahead to complete
12528         ls -l $DIR/$tdir.0 > /dev/null
12529
12530         testid=$(echo $TESTNAME | tr '_' ' ')
12531         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12532                 error "statahead warning" || true
12533 }
12534 run_test 123c "Can not initialize inode warning on DNE statahead"
12535
12536 test_124a() {
12537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12538         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12539                 skip_env "no lru resize on server"
12540
12541         local NR=2000
12542
12543         test_mkdir $DIR/$tdir
12544
12545         log "create $NR files at $DIR/$tdir"
12546         createmany -o $DIR/$tdir/f $NR ||
12547                 error "failed to create $NR files in $DIR/$tdir"
12548
12549         cancel_lru_locks mdc
12550         ls -l $DIR/$tdir > /dev/null
12551
12552         local NSDIR=""
12553         local LRU_SIZE=0
12554         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12555                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12556                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12557                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12558                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12559                         log "NSDIR=$NSDIR"
12560                         log "NS=$(basename $NSDIR)"
12561                         break
12562                 fi
12563         done
12564
12565         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12566                 skip "Not enough cached locks created!"
12567         fi
12568         log "LRU=$LRU_SIZE"
12569
12570         local SLEEP=30
12571
12572         # We know that lru resize allows one client to hold $LIMIT locks
12573         # for 10h. After that locks begin to be killed by client.
12574         local MAX_HRS=10
12575         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12576         log "LIMIT=$LIMIT"
12577         if [ $LIMIT -lt $LRU_SIZE ]; then
12578                 skip "Limit is too small $LIMIT"
12579         fi
12580
12581         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12582         # killing locks. Some time was spent for creating locks. This means
12583         # that up to the moment of sleep finish we must have killed some of
12584         # them (10-100 locks). This depends on how fast ther were created.
12585         # Many of them were touched in almost the same moment and thus will
12586         # be killed in groups.
12587         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12588
12589         # Use $LRU_SIZE_B here to take into account real number of locks
12590         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12591         local LRU_SIZE_B=$LRU_SIZE
12592         log "LVF=$LVF"
12593         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12594         log "OLD_LVF=$OLD_LVF"
12595         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12596
12597         # Let's make sure that we really have some margin. Client checks
12598         # cached locks every 10 sec.
12599         SLEEP=$((SLEEP+20))
12600         log "Sleep ${SLEEP} sec"
12601         local SEC=0
12602         while ((SEC<$SLEEP)); do
12603                 echo -n "..."
12604                 sleep 5
12605                 SEC=$((SEC+5))
12606                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12607                 echo -n "$LRU_SIZE"
12608         done
12609         echo ""
12610         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12611         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12612
12613         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12614                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12615                 unlinkmany $DIR/$tdir/f $NR
12616                 return
12617         }
12618
12619         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12620         log "unlink $NR files at $DIR/$tdir"
12621         unlinkmany $DIR/$tdir/f $NR
12622 }
12623 run_test 124a "lru resize ======================================="
12624
12625 get_max_pool_limit()
12626 {
12627         local limit=$($LCTL get_param \
12628                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12629         local max=0
12630         for l in $limit; do
12631                 if [[ $l -gt $max ]]; then
12632                         max=$l
12633                 fi
12634         done
12635         echo $max
12636 }
12637
12638 test_124b() {
12639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12640         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12641                 skip_env "no lru resize on server"
12642
12643         LIMIT=$(get_max_pool_limit)
12644
12645         NR=$(($(default_lru_size)*20))
12646         if [[ $NR -gt $LIMIT ]]; then
12647                 log "Limit lock number by $LIMIT locks"
12648                 NR=$LIMIT
12649         fi
12650
12651         IFree=$(mdsrate_inodes_available)
12652         if [ $IFree -lt $NR ]; then
12653                 log "Limit lock number by $IFree inodes"
12654                 NR=$IFree
12655         fi
12656
12657         lru_resize_disable mdc
12658         test_mkdir -p $DIR/$tdir/disable_lru_resize
12659
12660         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12661         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12662         cancel_lru_locks mdc
12663         stime=`date +%s`
12664         PID=""
12665         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12666         PID="$PID $!"
12667         sleep 2
12668         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12669         PID="$PID $!"
12670         sleep 2
12671         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12672         PID="$PID $!"
12673         wait $PID
12674         etime=`date +%s`
12675         nolruresize_delta=$((etime-stime))
12676         log "ls -la time: $nolruresize_delta seconds"
12677         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12678         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12679
12680         lru_resize_enable mdc
12681         test_mkdir -p $DIR/$tdir/enable_lru_resize
12682
12683         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12684         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12685         cancel_lru_locks mdc
12686         stime=`date +%s`
12687         PID=""
12688         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12689         PID="$PID $!"
12690         sleep 2
12691         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12692         PID="$PID $!"
12693         sleep 2
12694         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12695         PID="$PID $!"
12696         wait $PID
12697         etime=`date +%s`
12698         lruresize_delta=$((etime-stime))
12699         log "ls -la time: $lruresize_delta seconds"
12700         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12701
12702         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12703                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12704         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12705                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12706         else
12707                 log "lru resize performs the same with no lru resize"
12708         fi
12709         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12710 }
12711 run_test 124b "lru resize (performance test) ======================="
12712
12713 test_124c() {
12714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12715         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12716                 skip_env "no lru resize on server"
12717
12718         # cache ununsed locks on client
12719         local nr=100
12720         cancel_lru_locks mdc
12721         test_mkdir $DIR/$tdir
12722         createmany -o $DIR/$tdir/f $nr ||
12723                 error "failed to create $nr files in $DIR/$tdir"
12724         ls -l $DIR/$tdir > /dev/null
12725
12726         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12727         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12728         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12729         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12730         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12731
12732         # set lru_max_age to 1 sec
12733         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12734         echo "sleep $((recalc_p * 2)) seconds..."
12735         sleep $((recalc_p * 2))
12736
12737         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12738         # restore lru_max_age
12739         $LCTL set_param -n $nsdir.lru_max_age $max_age
12740         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12741         unlinkmany $DIR/$tdir/f $nr
12742 }
12743 run_test 124c "LRUR cancel very aged locks"
12744
12745 test_124d() {
12746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12747         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12748                 skip_env "no lru resize on server"
12749
12750         # cache ununsed locks on client
12751         local nr=100
12752
12753         lru_resize_disable mdc
12754         stack_trap "lru_resize_enable mdc" EXIT
12755
12756         cancel_lru_locks mdc
12757
12758         # asynchronous object destroy at MDT could cause bl ast to client
12759         test_mkdir $DIR/$tdir
12760         createmany -o $DIR/$tdir/f $nr ||
12761                 error "failed to create $nr files in $DIR/$tdir"
12762         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12763
12764         ls -l $DIR/$tdir > /dev/null
12765
12766         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12767         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12768         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12769         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12770
12771         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12772
12773         # set lru_max_age to 1 sec
12774         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12775         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12776
12777         echo "sleep $((recalc_p * 2)) seconds..."
12778         sleep $((recalc_p * 2))
12779
12780         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12781
12782         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12783 }
12784 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12785
12786 test_125() { # 13358
12787         $LCTL get_param -n llite.*.client_type | grep -q local ||
12788                 skip "must run as local client"
12789         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12790                 skip_env "must have acl enabled"
12791         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12792
12793         test_mkdir $DIR/$tdir
12794         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12795         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12796         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12797 }
12798 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12799
12800 test_126() { # bug 12829/13455
12801         $GSS && skip_env "must run as gss disabled"
12802         $LCTL get_param -n llite.*.client_type | grep -q local ||
12803                 skip "must run as local client"
12804         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12805
12806         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12807         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12808         rm -f $DIR/$tfile
12809         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12810 }
12811 run_test 126 "check that the fsgid provided by the client is taken into account"
12812
12813 test_127a() { # bug 15521
12814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12815         local name count samp unit min max sum sumsq
12816
12817         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12818         echo "stats before reset"
12819         $LCTL get_param osc.*.stats
12820         $LCTL set_param osc.*.stats=0
12821         local fsize=$((2048 * 1024))
12822
12823         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12824         cancel_lru_locks osc
12825         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12826
12827         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12828         stack_trap "rm -f $TMP/$tfile.tmp"
12829         while read name count samp unit min max sum sumsq; do
12830                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12831                 [ ! $min ] && error "Missing min value for $name proc entry"
12832                 eval $name=$count || error "Wrong proc format"
12833
12834                 case $name in
12835                 read_bytes|write_bytes)
12836                         [[ "$unit" =~ "bytes" ]] ||
12837                                 error "unit is not 'bytes': $unit"
12838                         (( $min >= 4096 )) || error "min is too small: $min"
12839                         (( $min <= $fsize )) || error "min is too big: $min"
12840                         (( $max >= 4096 )) || error "max is too small: $max"
12841                         (( $max <= $fsize )) || error "max is too big: $max"
12842                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12843                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12844                                 error "sumsquare is too small: $sumsq"
12845                         (( $sumsq <= $fsize * $fsize )) ||
12846                                 error "sumsquare is too big: $sumsq"
12847                         ;;
12848                 ost_read|ost_write)
12849                         [[ "$unit" =~ "usec" ]] ||
12850                                 error "unit is not 'usec': $unit"
12851                         ;;
12852                 *)      ;;
12853                 esac
12854         done < $DIR/$tfile.tmp
12855
12856         #check that we actually got some stats
12857         [ "$read_bytes" ] || error "Missing read_bytes stats"
12858         [ "$write_bytes" ] || error "Missing write_bytes stats"
12859         [ "$read_bytes" != 0 ] || error "no read done"
12860         [ "$write_bytes" != 0 ] || error "no write done"
12861 }
12862 run_test 127a "verify the client stats are sane"
12863
12864 test_127b() { # bug LU-333
12865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12866         local name count samp unit min max sum sumsq
12867
12868         echo "stats before reset"
12869         $LCTL get_param llite.*.stats
12870         $LCTL set_param llite.*.stats=0
12871
12872         # perform 2 reads and writes so MAX is different from SUM.
12873         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12874         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12875         cancel_lru_locks osc
12876         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12877         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12878
12879         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12880         stack_trap "rm -f $TMP/$tfile.tmp"
12881         while read name count samp unit min max sum sumsq; do
12882                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12883                 eval $name=$count || error "Wrong proc format"
12884
12885                 case $name in
12886                 read_bytes|write_bytes)
12887                         [[ "$unit" =~ "bytes" ]] ||
12888                                 error "unit is not 'bytes': $unit"
12889                         (( $count == 2 )) || error "count is not 2: $count"
12890                         (( $min == $PAGE_SIZE )) ||
12891                                 error "min is not $PAGE_SIZE: $min"
12892                         (( $max == $PAGE_SIZE )) ||
12893                                 error "max is not $PAGE_SIZE: $max"
12894                         (( $sum == $PAGE_SIZE * 2 )) ||
12895                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12896                         ;;
12897                 read|write)
12898                         [[ "$unit" =~ "usec" ]] ||
12899                                 error "unit is not 'usec': $unit"
12900                         ;;
12901                 *)      ;;
12902                 esac
12903         done < $TMP/$tfile.tmp
12904
12905         #check that we actually got some stats
12906         [ "$read_bytes" ] || error "Missing read_bytes stats"
12907         [ "$write_bytes" ] || error "Missing write_bytes stats"
12908         [ "$read_bytes" != 0 ] || error "no read done"
12909         [ "$write_bytes" != 0 ] || error "no write done"
12910 }
12911 run_test 127b "verify the llite client stats are sane"
12912
12913 test_127c() { # LU-12394
12914         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12915         local size
12916         local bsize
12917         local reads
12918         local writes
12919         local count
12920
12921         $LCTL set_param llite.*.extents_stats=1
12922         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12923
12924         # Use two stripes so there is enough space in default config
12925         $LFS setstripe -c 2 $DIR/$tfile
12926
12927         # Extent stats start at 0-4K and go in power of two buckets
12928         # LL_HIST_START = 12 --> 2^12 = 4K
12929         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12930         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12931         # small configs
12932         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12933                 do
12934                 # Write and read, 2x each, second time at a non-zero offset
12935                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12936                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12937                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12938                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12939                 rm -f $DIR/$tfile
12940         done
12941
12942         $LCTL get_param llite.*.extents_stats
12943
12944         count=2
12945         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12946                 do
12947                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12948                                 grep -m 1 $bsize)
12949                 reads=$(echo $bucket | awk '{print $5}')
12950                 writes=$(echo $bucket | awk '{print $9}')
12951                 [ "$reads" -eq $count ] ||
12952                         error "$reads reads in < $bsize bucket, expect $count"
12953                 [ "$writes" -eq $count ] ||
12954                         error "$writes writes in < $bsize bucket, expect $count"
12955         done
12956
12957         # Test mmap write and read
12958         $LCTL set_param llite.*.extents_stats=c
12959         size=512
12960         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12961         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12962         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12963
12964         $LCTL get_param llite.*.extents_stats
12965
12966         count=$(((size*1024) / PAGE_SIZE))
12967
12968         bsize=$((2 * PAGE_SIZE / 1024))K
12969
12970         bucket=$($LCTL get_param -n llite.*.extents_stats |
12971                         grep -m 1 $bsize)
12972         reads=$(echo $bucket | awk '{print $5}')
12973         writes=$(echo $bucket | awk '{print $9}')
12974         # mmap writes fault in the page first, creating an additonal read
12975         [ "$reads" -eq $((2 * count)) ] ||
12976                 error "$reads reads in < $bsize bucket, expect $count"
12977         [ "$writes" -eq $count ] ||
12978                 error "$writes writes in < $bsize bucket, expect $count"
12979 }
12980 run_test 127c "test llite extent stats with regular & mmap i/o"
12981
12982 test_128() { # bug 15212
12983         touch $DIR/$tfile
12984         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12985                 find $DIR/$tfile
12986                 find $DIR/$tfile
12987         EOF
12988
12989         result=$(grep error $TMP/$tfile.log)
12990         rm -f $DIR/$tfile $TMP/$tfile.log
12991         [ -z "$result" ] ||
12992                 error "consecutive find's under interactive lfs failed"
12993 }
12994 run_test 128 "interactive lfs for 2 consecutive find's"
12995
12996 set_dir_limits () {
12997         local mntdev
12998         local canondev
12999         local node
13000
13001         local ldproc=/proc/fs/ldiskfs
13002         local facets=$(get_facets MDS)
13003
13004         for facet in ${facets//,/ }; do
13005                 canondev=$(ldiskfs_canon \
13006                            *.$(convert_facet2label $facet).mntdev $facet)
13007                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13008                         ldproc=/sys/fs/ldiskfs
13009                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13010                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13011         done
13012 }
13013
13014 check_mds_dmesg() {
13015         local facets=$(get_facets MDS)
13016         for facet in ${facets//,/ }; do
13017                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13018         done
13019         return 1
13020 }
13021
13022 test_129() {
13023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13024         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13025                 skip "Need MDS version with at least 2.5.56"
13026         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13027                 skip_env "ldiskfs only test"
13028         fi
13029         remote_mds_nodsh && skip "remote MDS with nodsh"
13030
13031         local ENOSPC=28
13032         local has_warning=false
13033
13034         rm -rf $DIR/$tdir
13035         mkdir -p $DIR/$tdir
13036
13037         # block size of mds1
13038         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13039         set_dir_limits $maxsize $((maxsize * 6 / 8))
13040         stack_trap "set_dir_limits 0 0"
13041         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13042         local dirsize=$(stat -c%s "$DIR/$tdir")
13043         local nfiles=0
13044         while (( $dirsize <= $maxsize )); do
13045                 $MCREATE $DIR/$tdir/file_base_$nfiles
13046                 rc=$?
13047                 # check two errors:
13048                 # ENOSPC for ext4 max_dir_size, which has been used since
13049                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13050                 if (( rc == ENOSPC )); then
13051                         set_dir_limits 0 0
13052                         echo "rc=$rc returned as expected after $nfiles files"
13053
13054                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13055                                 error "create failed w/o dir size limit"
13056
13057                         # messages may be rate limited if test is run repeatedly
13058                         check_mds_dmesg '"is approaching max"' ||
13059                                 echo "warning message should be output"
13060                         check_mds_dmesg '"has reached max"' ||
13061                                 echo "reached message should be output"
13062
13063                         dirsize=$(stat -c%s "$DIR/$tdir")
13064
13065                         [[ $dirsize -ge $maxsize ]] && return 0
13066                         error "dirsize $dirsize < $maxsize after $nfiles files"
13067                 elif (( rc != 0 )); then
13068                         break
13069                 fi
13070                 nfiles=$((nfiles + 1))
13071                 dirsize=$(stat -c%s "$DIR/$tdir")
13072         done
13073
13074         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13075 }
13076 run_test 129 "test directory size limit ========================"
13077
13078 OLDIFS="$IFS"
13079 cleanup_130() {
13080         trap 0
13081         IFS="$OLDIFS"
13082 }
13083
13084 test_130a() {
13085         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13086         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13087
13088         trap cleanup_130 EXIT RETURN
13089
13090         local fm_file=$DIR/$tfile
13091         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13092         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13093                 error "dd failed for $fm_file"
13094
13095         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13096         filefrag -ves $fm_file
13097         RC=$?
13098         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13099                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13100         [ $RC != 0 ] && error "filefrag $fm_file failed"
13101
13102         filefrag_op=$(filefrag -ve -k $fm_file |
13103                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13104         lun=$($LFS getstripe -i $fm_file)
13105
13106         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13107         IFS=$'\n'
13108         tot_len=0
13109         for line in $filefrag_op
13110         do
13111                 frag_lun=`echo $line | cut -d: -f5`
13112                 ext_len=`echo $line | cut -d: -f4`
13113                 if (( $frag_lun != $lun )); then
13114                         cleanup_130
13115                         error "FIEMAP on 1-stripe file($fm_file) failed"
13116                         return
13117                 fi
13118                 (( tot_len += ext_len ))
13119         done
13120
13121         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13122                 cleanup_130
13123                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13124                 return
13125         fi
13126
13127         cleanup_130
13128
13129         echo "FIEMAP on single striped file succeeded"
13130 }
13131 run_test 130a "FIEMAP (1-stripe file)"
13132
13133 test_130b() {
13134         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13135
13136         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13137         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13138
13139         trap cleanup_130 EXIT RETURN
13140
13141         local fm_file=$DIR/$tfile
13142         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13143                         error "setstripe on $fm_file"
13144         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13145                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13146
13147         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13148                 error "dd failed on $fm_file"
13149
13150         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13151         filefrag_op=$(filefrag -ve -k $fm_file |
13152                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13153
13154         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13155                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13156
13157         IFS=$'\n'
13158         tot_len=0
13159         num_luns=1
13160         for line in $filefrag_op
13161         do
13162                 frag_lun=$(echo $line | cut -d: -f5 |
13163                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13164                 ext_len=$(echo $line | cut -d: -f4)
13165                 if (( $frag_lun != $last_lun )); then
13166                         if (( tot_len != 1024 )); then
13167                                 cleanup_130
13168                                 error "FIEMAP on $fm_file failed; returned " \
13169                                 "len $tot_len for OST $last_lun instead of 1024"
13170                                 return
13171                         else
13172                                 (( num_luns += 1 ))
13173                                 tot_len=0
13174                         fi
13175                 fi
13176                 (( tot_len += ext_len ))
13177                 last_lun=$frag_lun
13178         done
13179         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13180                 cleanup_130
13181                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13182                         "luns or wrong len for OST $last_lun"
13183                 return
13184         fi
13185
13186         cleanup_130
13187
13188         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13189 }
13190 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13191
13192 test_130c() {
13193         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13194
13195         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13196         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13197
13198         trap cleanup_130 EXIT RETURN
13199
13200         local fm_file=$DIR/$tfile
13201         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13202         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13203                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13204
13205         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13206                         error "dd failed on $fm_file"
13207
13208         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13209         filefrag_op=$(filefrag -ve -k $fm_file |
13210                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13211
13212         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13213                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13214
13215         IFS=$'\n'
13216         tot_len=0
13217         num_luns=1
13218         for line in $filefrag_op
13219         do
13220                 frag_lun=$(echo $line | cut -d: -f5 |
13221                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13222                 ext_len=$(echo $line | cut -d: -f4)
13223                 if (( $frag_lun != $last_lun )); then
13224                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13225                         if (( logical != 512 )); then
13226                                 cleanup_130
13227                                 error "FIEMAP on $fm_file failed; returned " \
13228                                 "logical start for lun $logical instead of 512"
13229                                 return
13230                         fi
13231                         if (( tot_len != 512 )); then
13232                                 cleanup_130
13233                                 error "FIEMAP on $fm_file failed; returned " \
13234                                 "len $tot_len for OST $last_lun instead of 1024"
13235                                 return
13236                         else
13237                                 (( num_luns += 1 ))
13238                                 tot_len=0
13239                         fi
13240                 fi
13241                 (( tot_len += ext_len ))
13242                 last_lun=$frag_lun
13243         done
13244         if (( num_luns != 2 || tot_len != 512 )); then
13245                 cleanup_130
13246                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13247                         "luns or wrong len for OST $last_lun"
13248                 return
13249         fi
13250
13251         cleanup_130
13252
13253         echo "FIEMAP on 2-stripe file with hole succeeded"
13254 }
13255 run_test 130c "FIEMAP (2-stripe file with hole)"
13256
13257 test_130d() {
13258         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13259
13260         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13261         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13262
13263         trap cleanup_130 EXIT RETURN
13264
13265         local fm_file=$DIR/$tfile
13266         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13267                         error "setstripe on $fm_file"
13268         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13269                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13270
13271         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13272         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13273                 error "dd failed on $fm_file"
13274
13275         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13276         filefrag_op=$(filefrag -ve -k $fm_file |
13277                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13278
13279         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13280                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13281
13282         IFS=$'\n'
13283         tot_len=0
13284         num_luns=1
13285         for line in $filefrag_op
13286         do
13287                 frag_lun=$(echo $line | cut -d: -f5 |
13288                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13289                 ext_len=$(echo $line | cut -d: -f4)
13290                 if (( $frag_lun != $last_lun )); then
13291                         if (( tot_len != 1024 )); then
13292                                 cleanup_130
13293                                 error "FIEMAP on $fm_file failed; returned " \
13294                                 "len $tot_len for OST $last_lun instead of 1024"
13295                                 return
13296                         else
13297                                 (( num_luns += 1 ))
13298                                 tot_len=0
13299                         fi
13300                 fi
13301                 (( tot_len += ext_len ))
13302                 last_lun=$frag_lun
13303         done
13304         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13305                 cleanup_130
13306                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13307                         "luns or wrong len for OST $last_lun"
13308                 return
13309         fi
13310
13311         cleanup_130
13312
13313         echo "FIEMAP on N-stripe file succeeded"
13314 }
13315 run_test 130d "FIEMAP (N-stripe file)"
13316
13317 test_130e() {
13318         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13319
13320         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13321         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13322
13323         trap cleanup_130 EXIT RETURN
13324
13325         local fm_file=$DIR/$tfile
13326         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13327
13328         NUM_BLKS=512
13329         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13330         for ((i = 0; i < $NUM_BLKS; i++)); do
13331                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13332                         conv=notrunc > /dev/null 2>&1
13333         done
13334
13335         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13336         filefrag_op=$(filefrag -ve -k $fm_file |
13337                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13338
13339         last_lun=$(echo $filefrag_op | cut -d: -f5)
13340
13341         IFS=$'\n'
13342         tot_len=0
13343         num_luns=1
13344         for line in $filefrag_op; do
13345                 frag_lun=$(echo $line | cut -d: -f5)
13346                 ext_len=$(echo $line | cut -d: -f4)
13347                 if [[ "$frag_lun" != "$last_lun" ]]; then
13348                         if (( tot_len != $EXPECTED_LEN )); then
13349                                 cleanup_130
13350                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13351                         else
13352                                 (( num_luns += 1 ))
13353                                 tot_len=0
13354                         fi
13355                 fi
13356                 (( tot_len += ext_len ))
13357                 last_lun=$frag_lun
13358         done
13359         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13360                 cleanup_130
13361                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13362         fi
13363
13364         echo "FIEMAP with continuation calls succeeded"
13365 }
13366 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13367
13368 test_130f() {
13369         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13370         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13371
13372         local fm_file=$DIR/$tfile
13373         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13374                 error "multiop create with lov_delay_create on $fm_file"
13375
13376         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13377         filefrag_extents=$(filefrag -vek $fm_file |
13378                            awk '/extents? found/ { print $2 }')
13379         if [[ "$filefrag_extents" != "0" ]]; then
13380                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13381         fi
13382
13383         rm -f $fm_file
13384 }
13385 run_test 130f "FIEMAP (unstriped file)"
13386
13387 test_130g() {
13388         local file=$DIR/$tfile
13389         local nr=$((OSTCOUNT * 100))
13390
13391         $LFS setstripe -C $nr $file ||
13392                 error "failed to setstripe -C $nr $file"
13393
13394         dd if=/dev/zero of=$file count=$nr bs=1M
13395         sync
13396         nr=$($LFS getstripe -c $file)
13397
13398         local extents=$(filefrag -v $file |
13399                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13400
13401         echo "filefrag list $extents extents in file with stripecount $nr"
13402         if (( extents < nr )); then
13403                 $LFS getstripe $file
13404                 filefrag -v $file
13405                 error "filefrag printed $extents < $nr extents"
13406         fi
13407
13408         rm -f $file
13409 }
13410 run_test 130g "FIEMAP (overstripe file)"
13411
13412 # Test for writev/readv
13413 test_131a() {
13414         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13415                 error "writev test failed"
13416         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13417                 error "readv failed"
13418         rm -f $DIR/$tfile
13419 }
13420 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13421
13422 test_131b() {
13423         local fsize=$((524288 + 1048576 + 1572864))
13424         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13425                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13426                         error "append writev test failed"
13427
13428         ((fsize += 1572864 + 1048576))
13429         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13430                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13431                         error "append writev test failed"
13432         rm -f $DIR/$tfile
13433 }
13434 run_test 131b "test append writev"
13435
13436 test_131c() {
13437         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13438         error "NOT PASS"
13439 }
13440 run_test 131c "test read/write on file w/o objects"
13441
13442 test_131d() {
13443         rwv -f $DIR/$tfile -w -n 1 1572864
13444         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13445         if [ "$NOB" != 1572864 ]; then
13446                 error "Short read filed: read $NOB bytes instead of 1572864"
13447         fi
13448         rm -f $DIR/$tfile
13449 }
13450 run_test 131d "test short read"
13451
13452 test_131e() {
13453         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13454         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13455         error "read hitting hole failed"
13456         rm -f $DIR/$tfile
13457 }
13458 run_test 131e "test read hitting hole"
13459
13460 check_stats() {
13461         local facet=$1
13462         local op=$2
13463         local want=${3:-0}
13464         local res
13465
13466         case $facet in
13467         mds*) res=$(do_facet $facet \
13468                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13469                  ;;
13470         ost*) res=$(do_facet $facet \
13471                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13472                  ;;
13473         *) error "Wrong facet '$facet'" ;;
13474         esac
13475         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13476         # if the argument $3 is zero, it means any stat increment is ok.
13477         if [[ $want -gt 0 ]]; then
13478                 local count=$(echo $res | awk '{ print $2 }')
13479                 [[ $count -ne $want ]] &&
13480                         error "The $op counter on $facet is $count, not $want"
13481         fi
13482 }
13483
13484 test_133a() {
13485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13486         remote_ost_nodsh && skip "remote OST with nodsh"
13487         remote_mds_nodsh && skip "remote MDS with nodsh"
13488         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13489                 skip_env "MDS doesn't support rename stats"
13490
13491         local testdir=$DIR/${tdir}/stats_testdir
13492
13493         mkdir -p $DIR/${tdir}
13494
13495         # clear stats.
13496         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13497         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13498
13499         # verify mdt stats first.
13500         mkdir ${testdir} || error "mkdir failed"
13501         check_stats $SINGLEMDS "mkdir" 1
13502         touch ${testdir}/${tfile} || error "touch failed"
13503         check_stats $SINGLEMDS "open" 1
13504         check_stats $SINGLEMDS "close" 1
13505         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13506                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13507                 check_stats $SINGLEMDS "mknod" 2
13508         }
13509         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13510         check_stats $SINGLEMDS "unlink" 1
13511         rm -f ${testdir}/${tfile} || error "file remove failed"
13512         check_stats $SINGLEMDS "unlink" 2
13513
13514         # remove working dir and check mdt stats again.
13515         rmdir ${testdir} || error "rmdir failed"
13516         check_stats $SINGLEMDS "rmdir" 1
13517
13518         local testdir1=$DIR/${tdir}/stats_testdir1
13519         mkdir -p ${testdir}
13520         mkdir -p ${testdir1}
13521         touch ${testdir1}/test1
13522         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13523         check_stats $SINGLEMDS "crossdir_rename" 1
13524
13525         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13526         check_stats $SINGLEMDS "samedir_rename" 1
13527
13528         rm -rf $DIR/${tdir}
13529 }
13530 run_test 133a "Verifying MDT stats ========================================"
13531
13532 test_133b() {
13533         local res
13534
13535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13536         remote_ost_nodsh && skip "remote OST with nodsh"
13537         remote_mds_nodsh && skip "remote MDS with nodsh"
13538
13539         local testdir=$DIR/${tdir}/stats_testdir
13540
13541         mkdir -p ${testdir} || error "mkdir failed"
13542         touch ${testdir}/${tfile} || error "touch failed"
13543         cancel_lru_locks mdc
13544
13545         # clear stats.
13546         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13547         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13548
13549         # extra mdt stats verification.
13550         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13551         check_stats $SINGLEMDS "setattr" 1
13552         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13553         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13554         then            # LU-1740
13555                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13556                 check_stats $SINGLEMDS "getattr" 1
13557         fi
13558         rm -rf $DIR/${tdir}
13559
13560         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13561         # so the check below is not reliable
13562         [ $MDSCOUNT -eq 1 ] || return 0
13563
13564         # Sleep to avoid a cached response.
13565         #define OBD_STATFS_CACHE_SECONDS 1
13566         sleep 2
13567         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13568         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13569         $LFS df || error "lfs failed"
13570         check_stats $SINGLEMDS "statfs" 1
13571
13572         # check aggregated statfs (LU-10018)
13573         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13574                 return 0
13575         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13576                 return 0
13577         sleep 2
13578         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13579         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13580         df $DIR
13581         check_stats $SINGLEMDS "statfs" 1
13582
13583         # We want to check that the client didn't send OST_STATFS to
13584         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13585         # extra care is needed here.
13586         if remote_mds; then
13587                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13588                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13589
13590                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13591                 [ "$res" ] && error "OST got STATFS"
13592         fi
13593
13594         return 0
13595 }
13596 run_test 133b "Verifying extra MDT stats =================================="
13597
13598 test_133c() {
13599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13600         remote_ost_nodsh && skip "remote OST with nodsh"
13601         remote_mds_nodsh && skip "remote MDS with nodsh"
13602
13603         local testdir=$DIR/$tdir/stats_testdir
13604
13605         test_mkdir -p $testdir
13606
13607         # verify obdfilter stats.
13608         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13609         sync
13610         cancel_lru_locks osc
13611         wait_delete_completed
13612
13613         # clear stats.
13614         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13615         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13616
13617         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13618                 error "dd failed"
13619         sync
13620         cancel_lru_locks osc
13621         check_stats ost1 "write" 1
13622
13623         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13624         check_stats ost1 "read" 1
13625
13626         > $testdir/$tfile || error "truncate failed"
13627         check_stats ost1 "punch" 1
13628
13629         rm -f $testdir/$tfile || error "file remove failed"
13630         wait_delete_completed
13631         check_stats ost1 "destroy" 1
13632
13633         rm -rf $DIR/$tdir
13634 }
13635 run_test 133c "Verifying OST stats ========================================"
13636
13637 order_2() {
13638         local value=$1
13639         local orig=$value
13640         local order=1
13641
13642         while [ $value -ge 2 ]; do
13643                 order=$((order*2))
13644                 value=$((value/2))
13645         done
13646
13647         if [ $orig -gt $order ]; then
13648                 order=$((order*2))
13649         fi
13650         echo $order
13651 }
13652
13653 size_in_KMGT() {
13654     local value=$1
13655     local size=('K' 'M' 'G' 'T');
13656     local i=0
13657     local size_string=$value
13658
13659     while [ $value -ge 1024 ]; do
13660         if [ $i -gt 3 ]; then
13661             #T is the biggest unit we get here, if that is bigger,
13662             #just return XXXT
13663             size_string=${value}T
13664             break
13665         fi
13666         value=$((value >> 10))
13667         if [ $value -lt 1024 ]; then
13668             size_string=${value}${size[$i]}
13669             break
13670         fi
13671         i=$((i + 1))
13672     done
13673
13674     echo $size_string
13675 }
13676
13677 get_rename_size() {
13678         local size=$1
13679         local context=${2:-.}
13680         local sample=$(do_facet $SINGLEMDS $LCTL \
13681                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13682                 grep -A1 $context |
13683                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13684         echo $sample
13685 }
13686
13687 test_133d() {
13688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13689         remote_ost_nodsh && skip "remote OST with nodsh"
13690         remote_mds_nodsh && skip "remote MDS with nodsh"
13691         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13692                 skip_env "MDS doesn't support rename stats"
13693
13694         local testdir1=$DIR/${tdir}/stats_testdir1
13695         local testdir2=$DIR/${tdir}/stats_testdir2
13696         mkdir -p $DIR/${tdir}
13697
13698         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13699
13700         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13701         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13702
13703         createmany -o $testdir1/test 512 || error "createmany failed"
13704
13705         # check samedir rename size
13706         mv ${testdir1}/test0 ${testdir1}/test_0
13707
13708         local testdir1_size=$(ls -l $DIR/${tdir} |
13709                 awk '/stats_testdir1/ {print $5}')
13710         local testdir2_size=$(ls -l $DIR/${tdir} |
13711                 awk '/stats_testdir2/ {print $5}')
13712
13713         testdir1_size=$(order_2 $testdir1_size)
13714         testdir2_size=$(order_2 $testdir2_size)
13715
13716         testdir1_size=$(size_in_KMGT $testdir1_size)
13717         testdir2_size=$(size_in_KMGT $testdir2_size)
13718
13719         echo "source rename dir size: ${testdir1_size}"
13720         echo "target rename dir size: ${testdir2_size}"
13721
13722         local cmd="do_facet $SINGLEMDS $LCTL "
13723         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13724
13725         eval $cmd || error "$cmd failed"
13726         local samedir=$($cmd | grep 'same_dir')
13727         local same_sample=$(get_rename_size $testdir1_size)
13728         [ -z "$samedir" ] && error "samedir_rename_size count error"
13729         [[ $same_sample -eq 1 ]] ||
13730                 error "samedir_rename_size error $same_sample"
13731         echo "Check same dir rename stats success"
13732
13733         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13734
13735         # check crossdir rename size
13736         mv ${testdir1}/test_0 ${testdir2}/test_0
13737
13738         testdir1_size=$(ls -l $DIR/${tdir} |
13739                 awk '/stats_testdir1/ {print $5}')
13740         testdir2_size=$(ls -l $DIR/${tdir} |
13741                 awk '/stats_testdir2/ {print $5}')
13742
13743         testdir1_size=$(order_2 $testdir1_size)
13744         testdir2_size=$(order_2 $testdir2_size)
13745
13746         testdir1_size=$(size_in_KMGT $testdir1_size)
13747         testdir2_size=$(size_in_KMGT $testdir2_size)
13748
13749         echo "source rename dir size: ${testdir1_size}"
13750         echo "target rename dir size: ${testdir2_size}"
13751
13752         eval $cmd || error "$cmd failed"
13753         local crossdir=$($cmd | grep 'crossdir')
13754         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13755         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13756         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13757         [[ $src_sample -eq 1 ]] ||
13758                 error "crossdir_rename_size error $src_sample"
13759         [[ $tgt_sample -eq 1 ]] ||
13760                 error "crossdir_rename_size error $tgt_sample"
13761         echo "Check cross dir rename stats success"
13762         rm -rf $DIR/${tdir}
13763 }
13764 run_test 133d "Verifying rename_stats ========================================"
13765
13766 test_133e() {
13767         remote_mds_nodsh && skip "remote MDS with nodsh"
13768         remote_ost_nodsh && skip "remote OST with nodsh"
13769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13770
13771         local testdir=$DIR/${tdir}/stats_testdir
13772         local ctr f0 f1 bs=32768 count=42 sum
13773
13774         mkdir -p ${testdir} || error "mkdir failed"
13775
13776         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13777
13778         for ctr in {write,read}_bytes; do
13779                 sync
13780                 cancel_lru_locks osc
13781
13782                 do_facet ost1 $LCTL set_param -n \
13783                         "obdfilter.*.exports.clear=clear"
13784
13785                 if [ $ctr = write_bytes ]; then
13786                         f0=/dev/zero
13787                         f1=${testdir}/${tfile}
13788                 else
13789                         f0=${testdir}/${tfile}
13790                         f1=/dev/null
13791                 fi
13792
13793                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13794                         error "dd failed"
13795                 sync
13796                 cancel_lru_locks osc
13797
13798                 sum=$(do_facet ost1 $LCTL get_param \
13799                         "obdfilter.*.exports.*.stats" |
13800                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13801                                 $1 == ctr { sum += $7 }
13802                                 END { printf("%0.0f", sum) }')
13803
13804                 if ((sum != bs * count)); then
13805                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13806                 fi
13807         done
13808
13809         rm -rf $DIR/${tdir}
13810 }
13811 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13812
13813 test_133f() {
13814         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13815                 skip "too old lustre for get_param -R ($facet_ver)"
13816
13817         # verifying readability.
13818         $LCTL get_param -R '*' &> /dev/null
13819
13820         # Verifing writability with badarea_io.
13821         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13822                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13823                 error "client badarea_io failed"
13824
13825         # remount the FS in case writes/reads /proc break the FS
13826         cleanup || error "failed to unmount"
13827         setup || error "failed to setup"
13828 }
13829 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13830
13831 test_133g() {
13832         remote_mds_nodsh && skip "remote MDS with nodsh"
13833         remote_ost_nodsh && skip "remote OST with nodsh"
13834
13835         local facet
13836         for facet in mds1 ost1; do
13837                 local facet_ver=$(lustre_version_code $facet)
13838                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13839                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13840                 else
13841                         log "$facet: too old lustre for get_param -R"
13842                 fi
13843                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13844                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13845                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13846                                 xargs badarea_io" ||
13847                                         error "$facet badarea_io failed"
13848                 else
13849                         skip_noexit "$facet: too old lustre for get_param -R"
13850                 fi
13851         done
13852
13853         # remount the FS in case writes/reads /proc break the FS
13854         cleanup || error "failed to unmount"
13855         setup || error "failed to setup"
13856 }
13857 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13858
13859 test_133h() {
13860         remote_mds_nodsh && skip "remote MDS with nodsh"
13861         remote_ost_nodsh && skip "remote OST with nodsh"
13862         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13863                 skip "Need MDS version at least 2.9.54"
13864
13865         local facet
13866         for facet in client mds1 ost1; do
13867                 # Get the list of files that are missing the terminating newline
13868                 local plist=$(do_facet $facet
13869                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13870                 local ent
13871                 for ent in $plist; do
13872                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13873                                 awk -v FS='\v' -v RS='\v\v' \
13874                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13875                                         print FILENAME}'" 2>/dev/null)
13876                         [ -z $missing ] || {
13877                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13878                                 error "file does not end with newline: $facet-$ent"
13879                         }
13880                 done
13881         done
13882 }
13883 run_test 133h "Proc files should end with newlines"
13884
13885 test_134a() {
13886         remote_mds_nodsh && skip "remote MDS with nodsh"
13887         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13888                 skip "Need MDS version at least 2.7.54"
13889
13890         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13891         cancel_lru_locks mdc
13892
13893         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13894         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13895         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13896
13897         local nr=1000
13898         createmany -o $DIR/$tdir/f $nr ||
13899                 error "failed to create $nr files in $DIR/$tdir"
13900         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13901
13902         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13903         do_facet mds1 $LCTL set_param fail_loc=0x327
13904         do_facet mds1 $LCTL set_param fail_val=500
13905         touch $DIR/$tdir/m
13906
13907         echo "sleep 10 seconds ..."
13908         sleep 10
13909         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13910
13911         do_facet mds1 $LCTL set_param fail_loc=0
13912         do_facet mds1 $LCTL set_param fail_val=0
13913         [ $lck_cnt -lt $unused ] ||
13914                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13915
13916         rm $DIR/$tdir/m
13917         unlinkmany $DIR/$tdir/f $nr
13918 }
13919 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13920
13921 test_134b() {
13922         remote_mds_nodsh && skip "remote MDS with nodsh"
13923         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13924                 skip "Need MDS version at least 2.7.54"
13925
13926         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13927         cancel_lru_locks mdc
13928
13929         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13930                         ldlm.lock_reclaim_threshold_mb)
13931         # disable reclaim temporarily
13932         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13933
13934         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13935         do_facet mds1 $LCTL set_param fail_loc=0x328
13936         do_facet mds1 $LCTL set_param fail_val=500
13937
13938         $LCTL set_param debug=+trace
13939
13940         local nr=600
13941         createmany -o $DIR/$tdir/f $nr &
13942         local create_pid=$!
13943
13944         echo "Sleep $TIMEOUT seconds ..."
13945         sleep $TIMEOUT
13946         if ! ps -p $create_pid  > /dev/null 2>&1; then
13947                 do_facet mds1 $LCTL set_param fail_loc=0
13948                 do_facet mds1 $LCTL set_param fail_val=0
13949                 do_facet mds1 $LCTL set_param \
13950                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13951                 error "createmany finished incorrectly!"
13952         fi
13953         do_facet mds1 $LCTL set_param fail_loc=0
13954         do_facet mds1 $LCTL set_param fail_val=0
13955         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13956         wait $create_pid || return 1
13957
13958         unlinkmany $DIR/$tdir/f $nr
13959 }
13960 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13961
13962 test_135() {
13963         remote_mds_nodsh && skip "remote MDS with nodsh"
13964         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13965                 skip "Need MDS version at least 2.13.50"
13966         local fname
13967
13968         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13969
13970 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13971         #set only one record at plain llog
13972         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13973
13974         #fill already existed plain llog each 64767
13975         #wrapping whole catalog
13976         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13977
13978         createmany -o $DIR/$tdir/$tfile_ 64700
13979         for (( i = 0; i < 64700; i = i + 2 ))
13980         do
13981                 rm $DIR/$tdir/$tfile_$i &
13982                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13983                 local pid=$!
13984                 wait $pid
13985         done
13986
13987         #waiting osp synchronization
13988         wait_delete_completed
13989 }
13990 run_test 135 "Race catalog processing"
13991
13992 test_136() {
13993         remote_mds_nodsh && skip "remote MDS with nodsh"
13994         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13995                 skip "Need MDS version at least 2.13.50"
13996         local fname
13997
13998         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13999         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14000         #set only one record at plain llog
14001 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14002         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14003
14004         #fill already existed 2 plain llogs each 64767
14005         #wrapping whole catalog
14006         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14007         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14008         wait_delete_completed
14009
14010         createmany -o $DIR/$tdir/$tfile_ 10
14011         sleep 25
14012
14013         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14014         for (( i = 0; i < 10; i = i + 3 ))
14015         do
14016                 rm $DIR/$tdir/$tfile_$i &
14017                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14018                 local pid=$!
14019                 wait $pid
14020                 sleep 7
14021                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14022         done
14023
14024         #waiting osp synchronization
14025         wait_delete_completed
14026 }
14027 run_test 136 "Race catalog processing 2"
14028
14029 test_140() { #bug-17379
14030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14031
14032         test_mkdir $DIR/$tdir
14033         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14034         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14035
14036         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14037         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14038         local i=0
14039         while i=$((i + 1)); do
14040                 test_mkdir $i
14041                 cd $i || error "Changing to $i"
14042                 ln -s ../stat stat || error "Creating stat symlink"
14043                 # Read the symlink until ELOOP present,
14044                 # not LBUGing the system is considered success,
14045                 # we didn't overrun the stack.
14046                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14047                 if [ $ret -ne 0 ]; then
14048                         if [ $ret -eq 40 ]; then
14049                                 break  # -ELOOP
14050                         else
14051                                 error "Open stat symlink"
14052                                         return
14053                         fi
14054                 fi
14055         done
14056         i=$((i - 1))
14057         echo "The symlink depth = $i"
14058         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14059                 error "Invalid symlink depth"
14060
14061         # Test recursive symlink
14062         ln -s symlink_self symlink_self
14063         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14064         echo "open symlink_self returns $ret"
14065         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14066 }
14067 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14068
14069 test_150a() {
14070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14071
14072         local TF="$TMP/$tfile"
14073
14074         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14075         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14076         cp $TF $DIR/$tfile
14077         cancel_lru_locks $OSC
14078         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14079         remount_client $MOUNT
14080         df -P $MOUNT
14081         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14082
14083         $TRUNCATE $TF 6000
14084         $TRUNCATE $DIR/$tfile 6000
14085         cancel_lru_locks $OSC
14086         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14087
14088         echo "12345" >>$TF
14089         echo "12345" >>$DIR/$tfile
14090         cancel_lru_locks $OSC
14091         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14092
14093         echo "12345" >>$TF
14094         echo "12345" >>$DIR/$tfile
14095         cancel_lru_locks $OSC
14096         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14097 }
14098 run_test 150a "truncate/append tests"
14099
14100 test_150b() {
14101         check_set_fallocate_or_skip
14102
14103         touch $DIR/$tfile
14104         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14105         check_fallocate $DIR/$tfile || error "fallocate failed"
14106 }
14107 run_test 150b "Verify fallocate (prealloc) functionality"
14108
14109 test_150bb() {
14110         check_set_fallocate_or_skip
14111
14112         touch $DIR/$tfile
14113         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14114         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14115         > $DIR/$tfile
14116         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14117         # precomputed md5sum for 20MB of zeroes
14118         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14119         local sum=($(md5sum $DIR/$tfile))
14120
14121         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14122
14123         check_set_fallocate 1
14124
14125         > $DIR/$tfile
14126         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14127         sum=($(md5sum $DIR/$tfile))
14128
14129         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14130 }
14131 run_test 150bb "Verify fallocate modes both zero space"
14132
14133 test_150c() {
14134         check_set_fallocate_or_skip
14135
14136         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14137         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14138         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14139         sync; sync_all_data
14140         cancel_lru_locks $OSC
14141         sleep 5
14142         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14143         want=$((OSTCOUNT * 1048576))
14144
14145         # Must allocate all requested space, not more than 5% extra
14146         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14147                 error "bytes $bytes is not $want"
14148
14149         rm -f $DIR/$tfile
14150         # verify fallocate on PFL file
14151         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14152                 error "Create $DIR/$tfile failed"
14153         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
14154                         error "fallocate failed"
14155         sync; sync_all_data
14156         cancel_lru_locks $OSC
14157         sleep 5
14158         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14159         local want=$((1024 * 1048576))
14160
14161         # Must allocate all requested space, not more than 5% extra
14162         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14163                 error "bytes $bytes is not $want"
14164 }
14165 run_test 150c "Verify fallocate Size and Blocks"
14166
14167 test_150d() {
14168         check_set_fallocate_or_skip
14169
14170         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14171         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14172         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14173         sync; sync_all_data
14174         cancel_lru_locks $OSC
14175         sleep 5
14176         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14177         local want=$((OSTCOUNT * 1048576))
14178
14179         # Must allocate all requested space, not more than 5% extra
14180         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14181                 error "bytes $bytes is not $want"
14182 }
14183 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14184
14185 test_150e() {
14186         check_set_fallocate_or_skip
14187
14188         echo "df before:"
14189         $LFS df
14190         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14191         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14192                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14193
14194         # Find OST with Minimum Size
14195         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14196                        sort -un | head -1)
14197
14198         # Get 100MB per OST of the available space to reduce run time
14199         # else 60% of the available space if we are running SLOW tests
14200         if [ $SLOW == "no" ]; then
14201                 local space=$((1024 * 100 * OSTCOUNT))
14202         else
14203                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14204         fi
14205
14206         fallocate -l${space}k $DIR/$tfile ||
14207                 error "fallocate ${space}k $DIR/$tfile failed"
14208         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14209
14210         # get size immediately after fallocate. This should be correctly
14211         # updated
14212         local size=$(stat -c '%s' $DIR/$tfile)
14213         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14214
14215         # Sleep for a while for statfs to get updated. And not pull from cache.
14216         sleep 2
14217
14218         echo "df after fallocate:"
14219         $LFS df
14220
14221         (( size / 1024 == space )) || error "size $size != requested $space"
14222         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14223                 error "used $used < space $space"
14224
14225         rm $DIR/$tfile || error "rm failed"
14226         sync
14227         wait_delete_completed
14228
14229         echo "df after unlink:"
14230         $LFS df
14231 }
14232 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14233
14234 test_150f() {
14235         local size
14236         local blocks
14237         local want_size_before=20480 # in bytes
14238         local want_blocks_before=40 # 512 sized blocks
14239         local want_blocks_after=24  # 512 sized blocks
14240         local length=$(((want_blocks_before - want_blocks_after) * 512))
14241
14242         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14243                 skip "need at least 2.14.0 for fallocate punch"
14244
14245         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14246                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14247         fi
14248
14249         check_set_fallocate_or_skip
14250         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14251
14252         echo "Verify fallocate punch: Range within the file range"
14253         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14254                 error "dd failed for bs 4096 and count 5"
14255
14256         # Call fallocate with punch range which is within the file range
14257         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14258                 error "fallocate failed: offset 4096 and length $length"
14259         # client must see changes immediately after fallocate
14260         size=$(stat -c '%s' $DIR/$tfile)
14261         blocks=$(stat -c '%b' $DIR/$tfile)
14262
14263         # Verify punch worked.
14264         (( blocks == want_blocks_after )) ||
14265                 error "punch failed: blocks $blocks != $want_blocks_after"
14266
14267         (( size == want_size_before )) ||
14268                 error "punch failed: size $size != $want_size_before"
14269
14270         # Verify there is hole in file
14271         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14272         # precomputed md5sum
14273         local expect="4a9a834a2db02452929c0a348273b4aa"
14274
14275         cksum=($(md5sum $DIR/$tfile))
14276         [[ "${cksum[0]}" == "$expect" ]] ||
14277                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14278
14279         # Start second sub-case for fallocate punch.
14280         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14281         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14282                 error "dd failed for bs 4096 and count 5"
14283
14284         # Punch range less than block size will have no change in block count
14285         want_blocks_after=40  # 512 sized blocks
14286
14287         # Punch overlaps two blocks and less than blocksize
14288         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14289                 error "fallocate failed: offset 4000 length 3000"
14290         size=$(stat -c '%s' $DIR/$tfile)
14291         blocks=$(stat -c '%b' $DIR/$tfile)
14292
14293         # Verify punch worked.
14294         (( blocks == want_blocks_after )) ||
14295                 error "punch failed: blocks $blocks != $want_blocks_after"
14296
14297         (( size == want_size_before )) ||
14298                 error "punch failed: size $size != $want_size_before"
14299
14300         # Verify if range is really zero'ed out. We expect Zeros.
14301         # precomputed md5sum
14302         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14303         cksum=($(md5sum $DIR/$tfile))
14304         [[ "${cksum[0]}" == "$expect" ]] ||
14305                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14306 }
14307 run_test 150f "Verify fallocate punch functionality"
14308
14309 test_150g() {
14310         local space
14311         local size
14312         local blocks
14313         local blocks_after
14314         local size_after
14315         local BS=4096 # Block size in bytes
14316
14317         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14318                 skip "need at least 2.14.0 for fallocate punch"
14319
14320         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14321                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14322         fi
14323
14324         check_set_fallocate_or_skip
14325         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14326
14327         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14328                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14329
14330         # Get 100MB per OST of the available space to reduce run time
14331         # else 60% of the available space if we are running SLOW tests
14332         if [ $SLOW == "no" ]; then
14333                 space=$((1024 * 100 * OSTCOUNT))
14334         else
14335                 # Find OST with Minimum Size
14336                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14337                         sort -un | head -1)
14338                 echo "min size OST: $space"
14339                 space=$(((space * 60)/100 * OSTCOUNT))
14340         fi
14341         # space in 1k units, round to 4k blocks
14342         local blkcount=$((space * 1024 / $BS))
14343
14344         echo "Verify fallocate punch: Very large Range"
14345         fallocate -l${space}k $DIR/$tfile ||
14346                 error "fallocate ${space}k $DIR/$tfile failed"
14347         # write 1M at the end, start and in the middle
14348         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14349                 error "dd failed: bs $BS count 256"
14350         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14351                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14352         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14353                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14354
14355         # Gather stats.
14356         size=$(stat -c '%s' $DIR/$tfile)
14357
14358         # gather punch length.
14359         local punch_size=$((size - (BS * 2)))
14360
14361         echo "punch_size = $punch_size"
14362         echo "size - punch_size: $((size - punch_size))"
14363         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14364
14365         # Call fallocate to punch all except 2 blocks. We leave the
14366         # first and the last block
14367         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14368         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14369                 error "fallocate failed: offset $BS length $punch_size"
14370
14371         size_after=$(stat -c '%s' $DIR/$tfile)
14372         blocks_after=$(stat -c '%b' $DIR/$tfile)
14373
14374         # Verify punch worked.
14375         # Size should be kept
14376         (( size == size_after )) ||
14377                 error "punch failed: size $size != $size_after"
14378
14379         # two 4k data blocks to remain plus possible 1 extra extent block
14380         (( blocks_after <= ((BS / 512) * 3) )) ||
14381                 error "too many blocks remains: $blocks_after"
14382
14383         # Verify that file has hole between the first and the last blocks
14384         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14385         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14386
14387         echo "Hole at [$hole_start, $hole_end)"
14388         (( hole_start == BS )) ||
14389                 error "no hole at offset $BS after punch"
14390
14391         (( hole_end == BS + punch_size )) ||
14392                 error "data at offset $hole_end < $((BS + punch_size))"
14393 }
14394 run_test 150g "Verify fallocate punch on large range"
14395
14396 #LU-2902 roc_hit was not able to read all values from lproc
14397 function roc_hit_init() {
14398         local list=$(comma_list $(osts_nodes))
14399         local dir=$DIR/$tdir-check
14400         local file=$dir/$tfile
14401         local BEFORE
14402         local AFTER
14403         local idx
14404
14405         test_mkdir $dir
14406         #use setstripe to do a write to every ost
14407         for i in $(seq 0 $((OSTCOUNT-1))); do
14408                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14409                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14410                 idx=$(printf %04x $i)
14411                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14412                         awk '$1 == "cache_access" {sum += $7}
14413                                 END { printf("%0.0f", sum) }')
14414
14415                 cancel_lru_locks osc
14416                 cat $file >/dev/null
14417
14418                 AFTER=$(get_osd_param $list *OST*$idx stats |
14419                         awk '$1 == "cache_access" {sum += $7}
14420                                 END { printf("%0.0f", sum) }')
14421
14422                 echo BEFORE:$BEFORE AFTER:$AFTER
14423                 if ! let "AFTER - BEFORE == 4"; then
14424                         rm -rf $dir
14425                         error "roc_hit is not safe to use"
14426                 fi
14427                 rm $file
14428         done
14429
14430         rm -rf $dir
14431 }
14432
14433 function roc_hit() {
14434         local list=$(comma_list $(osts_nodes))
14435         echo $(get_osd_param $list '' stats |
14436                 awk '$1 == "cache_hit" {sum += $7}
14437                         END { printf("%0.0f", sum) }')
14438 }
14439
14440 function set_cache() {
14441         local on=1
14442
14443         if [ "$2" == "off" ]; then
14444                 on=0;
14445         fi
14446         local list=$(comma_list $(osts_nodes))
14447         set_osd_param $list '' $1_cache_enable $on
14448
14449         cancel_lru_locks osc
14450 }
14451
14452 test_151() {
14453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14454         remote_ost_nodsh && skip "remote OST with nodsh"
14455
14456         local CPAGES=3
14457         local list=$(comma_list $(osts_nodes))
14458
14459         # check whether obdfilter is cache capable at all
14460         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14461                 skip "not cache-capable obdfilter"
14462         fi
14463
14464         # check cache is enabled on all obdfilters
14465         if get_osd_param $list '' read_cache_enable | grep 0; then
14466                 skip "oss cache is disabled"
14467         fi
14468
14469         set_osd_param $list '' writethrough_cache_enable 1
14470
14471         # check write cache is enabled on all obdfilters
14472         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14473                 skip "oss write cache is NOT enabled"
14474         fi
14475
14476         roc_hit_init
14477
14478         #define OBD_FAIL_OBD_NO_LRU  0x609
14479         do_nodes $list $LCTL set_param fail_loc=0x609
14480
14481         # pages should be in the case right after write
14482         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14483                 error "dd failed"
14484
14485         local BEFORE=$(roc_hit)
14486         cancel_lru_locks osc
14487         cat $DIR/$tfile >/dev/null
14488         local AFTER=$(roc_hit)
14489
14490         do_nodes $list $LCTL set_param fail_loc=0
14491
14492         if ! let "AFTER - BEFORE == CPAGES"; then
14493                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14494         fi
14495
14496         cancel_lru_locks osc
14497         # invalidates OST cache
14498         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14499         set_osd_param $list '' read_cache_enable 0
14500         cat $DIR/$tfile >/dev/null
14501
14502         # now data shouldn't be found in the cache
14503         BEFORE=$(roc_hit)
14504         cancel_lru_locks osc
14505         cat $DIR/$tfile >/dev/null
14506         AFTER=$(roc_hit)
14507         if let "AFTER - BEFORE != 0"; then
14508                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14509         fi
14510
14511         set_osd_param $list '' read_cache_enable 1
14512         rm -f $DIR/$tfile
14513 }
14514 run_test 151 "test cache on oss and controls ==============================="
14515
14516 test_152() {
14517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14518
14519         local TF="$TMP/$tfile"
14520
14521         # simulate ENOMEM during write
14522 #define OBD_FAIL_OST_NOMEM      0x226
14523         lctl set_param fail_loc=0x80000226
14524         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14525         cp $TF $DIR/$tfile
14526         sync || error "sync failed"
14527         lctl set_param fail_loc=0
14528
14529         # discard client's cache
14530         cancel_lru_locks osc
14531
14532         # simulate ENOMEM during read
14533         lctl set_param fail_loc=0x80000226
14534         cmp $TF $DIR/$tfile || error "cmp failed"
14535         lctl set_param fail_loc=0
14536
14537         rm -f $TF
14538 }
14539 run_test 152 "test read/write with enomem ============================"
14540
14541 test_153() {
14542         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14543 }
14544 run_test 153 "test if fdatasync does not crash ======================="
14545
14546 dot_lustre_fid_permission_check() {
14547         local fid=$1
14548         local ffid=$MOUNT/.lustre/fid/$fid
14549         local test_dir=$2
14550
14551         echo "stat fid $fid"
14552         stat $ffid > /dev/null || error "stat $ffid failed."
14553         echo "touch fid $fid"
14554         touch $ffid || error "touch $ffid failed."
14555         echo "write to fid $fid"
14556         cat /etc/hosts > $ffid || error "write $ffid failed."
14557         echo "read fid $fid"
14558         diff /etc/hosts $ffid || error "read $ffid failed."
14559         echo "append write to fid $fid"
14560         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14561         echo "rename fid $fid"
14562         mv $ffid $test_dir/$tfile.1 &&
14563                 error "rename $ffid to $tfile.1 should fail."
14564         touch $test_dir/$tfile.1
14565         mv $test_dir/$tfile.1 $ffid &&
14566                 error "rename $tfile.1 to $ffid should fail."
14567         rm -f $test_dir/$tfile.1
14568         echo "truncate fid $fid"
14569         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14570         echo "link fid $fid"
14571         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14572         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14573                 echo "setfacl fid $fid"
14574                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14575                 echo "getfacl fid $fid"
14576                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14577         fi
14578         echo "unlink fid $fid"
14579         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14580         echo "mknod fid $fid"
14581         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14582
14583         fid=[0xf00000400:0x1:0x0]
14584         ffid=$MOUNT/.lustre/fid/$fid
14585
14586         echo "stat non-exist fid $fid"
14587         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14588         echo "write to non-exist fid $fid"
14589         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14590         echo "link new fid $fid"
14591         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14592
14593         mkdir -p $test_dir/$tdir
14594         touch $test_dir/$tdir/$tfile
14595         fid=$($LFS path2fid $test_dir/$tdir)
14596         rc=$?
14597         [ $rc -ne 0 ] &&
14598                 error "error: could not get fid for $test_dir/$dir/$tfile."
14599
14600         ffid=$MOUNT/.lustre/fid/$fid
14601
14602         echo "ls $fid"
14603         ls $ffid > /dev/null || error "ls $ffid failed."
14604         echo "touch $fid/$tfile.1"
14605         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14606
14607         echo "touch $MOUNT/.lustre/fid/$tfile"
14608         touch $MOUNT/.lustre/fid/$tfile && \
14609                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14610
14611         echo "setxattr to $MOUNT/.lustre/fid"
14612         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14613
14614         echo "listxattr for $MOUNT/.lustre/fid"
14615         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14616
14617         echo "delxattr from $MOUNT/.lustre/fid"
14618         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14619
14620         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14621         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14622                 error "touch invalid fid should fail."
14623
14624         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14625         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14626                 error "touch non-normal fid should fail."
14627
14628         echo "rename $tdir to $MOUNT/.lustre/fid"
14629         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14630                 error "rename to $MOUNT/.lustre/fid should fail."
14631
14632         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14633         then            # LU-3547
14634                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14635                 local new_obf_mode=777
14636
14637                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14638                 chmod $new_obf_mode $DIR/.lustre/fid ||
14639                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14640
14641                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14642                 [ $obf_mode -eq $new_obf_mode ] ||
14643                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14644
14645                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14646                 chmod $old_obf_mode $DIR/.lustre/fid ||
14647                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14648         fi
14649
14650         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14651         fid=$($LFS path2fid $test_dir/$tfile-2)
14652
14653         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14654         then # LU-5424
14655                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14656                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14657                         error "create lov data thru .lustre failed"
14658         fi
14659         echo "cp /etc/passwd $test_dir/$tfile-2"
14660         cp /etc/passwd $test_dir/$tfile-2 ||
14661                 error "copy to $test_dir/$tfile-2 failed."
14662         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14663         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14664                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14665
14666         rm -rf $test_dir/tfile.lnk
14667         rm -rf $test_dir/$tfile-2
14668 }
14669
14670 test_154A() {
14671         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14672                 skip "Need MDS version at least 2.4.1"
14673
14674         local tf=$DIR/$tfile
14675         touch $tf
14676
14677         local fid=$($LFS path2fid $tf)
14678         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14679
14680         # check that we get the same pathname back
14681         local rootpath
14682         local found
14683         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14684                 echo "$rootpath $fid"
14685                 found=$($LFS fid2path $rootpath "$fid")
14686                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14687                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14688         done
14689
14690         # check wrong root path format
14691         rootpath=$MOUNT"_wrong"
14692         found=$($LFS fid2path $rootpath "$fid")
14693         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14694 }
14695 run_test 154A "lfs path2fid and fid2path basic checks"
14696
14697 test_154B() {
14698         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14699                 skip "Need MDS version at least 2.4.1"
14700
14701         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14702         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14703         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14704         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14705
14706         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14707         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14708
14709         # check that we get the same pathname
14710         echo "PFID: $PFID, name: $name"
14711         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14712         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14713         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14714                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14715
14716         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14717 }
14718 run_test 154B "verify the ll_decode_linkea tool"
14719
14720 test_154a() {
14721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14722         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14723         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14724                 skip "Need MDS version at least 2.2.51"
14725         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14726
14727         cp /etc/hosts $DIR/$tfile
14728
14729         fid=$($LFS path2fid $DIR/$tfile)
14730         rc=$?
14731         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14732
14733         dot_lustre_fid_permission_check "$fid" $DIR ||
14734                 error "dot lustre permission check $fid failed"
14735
14736         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14737
14738         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14739
14740         touch $MOUNT/.lustre/file &&
14741                 error "creation is not allowed under .lustre"
14742
14743         mkdir $MOUNT/.lustre/dir &&
14744                 error "mkdir is not allowed under .lustre"
14745
14746         rm -rf $DIR/$tfile
14747 }
14748 run_test 154a "Open-by-FID"
14749
14750 test_154b() {
14751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14752         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14754         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14755                 skip "Need MDS version at least 2.2.51"
14756
14757         local remote_dir=$DIR/$tdir/remote_dir
14758         local MDTIDX=1
14759         local rc=0
14760
14761         mkdir -p $DIR/$tdir
14762         $LFS mkdir -i $MDTIDX $remote_dir ||
14763                 error "create remote directory failed"
14764
14765         cp /etc/hosts $remote_dir/$tfile
14766
14767         fid=$($LFS path2fid $remote_dir/$tfile)
14768         rc=$?
14769         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14770
14771         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14772                 error "dot lustre permission check $fid failed"
14773         rm -rf $DIR/$tdir
14774 }
14775 run_test 154b "Open-by-FID for remote directory"
14776
14777 test_154c() {
14778         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14779                 skip "Need MDS version at least 2.4.1"
14780
14781         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14782         local FID1=$($LFS path2fid $DIR/$tfile.1)
14783         local FID2=$($LFS path2fid $DIR/$tfile.2)
14784         local FID3=$($LFS path2fid $DIR/$tfile.3)
14785
14786         local N=1
14787         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14788                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14789                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14790                 local want=FID$N
14791                 [ "$FID" = "${!want}" ] ||
14792                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14793                 N=$((N + 1))
14794         done
14795
14796         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14797         do
14798                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14799                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14800                 N=$((N + 1))
14801         done
14802 }
14803 run_test 154c "lfs path2fid and fid2path multiple arguments"
14804
14805 test_154d() {
14806         remote_mds_nodsh && skip "remote MDS with nodsh"
14807         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14808                 skip "Need MDS version at least 2.5.53"
14809
14810         if remote_mds; then
14811                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14812         else
14813                 nid="0@lo"
14814         fi
14815         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14816         local fd
14817         local cmd
14818
14819         rm -f $DIR/$tfile
14820         touch $DIR/$tfile
14821
14822         local fid=$($LFS path2fid $DIR/$tfile)
14823         # Open the file
14824         fd=$(free_fd)
14825         cmd="exec $fd<$DIR/$tfile"
14826         eval $cmd
14827         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14828         echo "$fid_list" | grep "$fid"
14829         rc=$?
14830
14831         cmd="exec $fd>/dev/null"
14832         eval $cmd
14833         if [ $rc -ne 0 ]; then
14834                 error "FID $fid not found in open files list $fid_list"
14835         fi
14836 }
14837 run_test 154d "Verify open file fid"
14838
14839 test_154e()
14840 {
14841         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14842                 skip "Need MDS version at least 2.6.50"
14843
14844         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14845                 error ".lustre returned by readdir"
14846         fi
14847 }
14848 run_test 154e ".lustre is not returned by readdir"
14849
14850 test_154f() {
14851         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14852
14853         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14854         test_mkdir -p -c1 $DIR/$tdir/d
14855         # test dirs inherit from its stripe
14856         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14857         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14858         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14859         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14860         touch $DIR/f
14861
14862         # get fid of parents
14863         local FID0=$($LFS path2fid $DIR/$tdir/d)
14864         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14865         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14866         local FID3=$($LFS path2fid $DIR)
14867
14868         # check that path2fid --parents returns expected <parent_fid>/name
14869         # 1) test for a directory (single parent)
14870         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14871         [ "$parent" == "$FID0/foo1" ] ||
14872                 error "expected parent: $FID0/foo1, got: $parent"
14873
14874         # 2) test for a file with nlink > 1 (multiple parents)
14875         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14876         echo "$parent" | grep -F "$FID1/$tfile" ||
14877                 error "$FID1/$tfile not returned in parent list"
14878         echo "$parent" | grep -F "$FID2/link" ||
14879                 error "$FID2/link not returned in parent list"
14880
14881         # 3) get parent by fid
14882         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14883         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14884         echo "$parent" | grep -F "$FID1/$tfile" ||
14885                 error "$FID1/$tfile not returned in parent list (by fid)"
14886         echo "$parent" | grep -F "$FID2/link" ||
14887                 error "$FID2/link not returned in parent list (by fid)"
14888
14889         # 4) test for entry in root directory
14890         parent=$($LFS path2fid --parents $DIR/f)
14891         echo "$parent" | grep -F "$FID3/f" ||
14892                 error "$FID3/f not returned in parent list"
14893
14894         # 5) test it on root directory
14895         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14896                 error "$MOUNT should not have parents"
14897
14898         # enable xattr caching and check that linkea is correctly updated
14899         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14900         save_lustre_params client "llite.*.xattr_cache" > $save
14901         lctl set_param llite.*.xattr_cache 1
14902
14903         # 6.1) linkea update on rename
14904         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14905
14906         # get parents by fid
14907         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14908         # foo1 should no longer be returned in parent list
14909         echo "$parent" | grep -F "$FID1" &&
14910                 error "$FID1 should no longer be in parent list"
14911         # the new path should appear
14912         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14913                 error "$FID2/$tfile.moved is not in parent list"
14914
14915         # 6.2) linkea update on unlink
14916         rm -f $DIR/$tdir/d/foo2/link
14917         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14918         # foo2/link should no longer be returned in parent list
14919         echo "$parent" | grep -F "$FID2/link" &&
14920                 error "$FID2/link should no longer be in parent list"
14921         true
14922
14923         rm -f $DIR/f
14924         restore_lustre_params < $save
14925         rm -f $save
14926 }
14927 run_test 154f "get parent fids by reading link ea"
14928
14929 test_154g()
14930 {
14931         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14932         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14933            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14934                 skip "Need MDS version at least 2.6.92"
14935
14936         mkdir -p $DIR/$tdir
14937         llapi_fid_test -d $DIR/$tdir
14938 }
14939 run_test 154g "various llapi FID tests"
14940
14941 test_155_small_load() {
14942     local temp=$TMP/$tfile
14943     local file=$DIR/$tfile
14944
14945     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14946         error "dd of=$temp bs=6096 count=1 failed"
14947     cp $temp $file
14948     cancel_lru_locks $OSC
14949     cmp $temp $file || error "$temp $file differ"
14950
14951     $TRUNCATE $temp 6000
14952     $TRUNCATE $file 6000
14953     cmp $temp $file || error "$temp $file differ (truncate1)"
14954
14955     echo "12345" >>$temp
14956     echo "12345" >>$file
14957     cmp $temp $file || error "$temp $file differ (append1)"
14958
14959     echo "12345" >>$temp
14960     echo "12345" >>$file
14961     cmp $temp $file || error "$temp $file differ (append2)"
14962
14963     rm -f $temp $file
14964     true
14965 }
14966
14967 test_155_big_load() {
14968         remote_ost_nodsh && skip "remote OST with nodsh"
14969
14970         local temp=$TMP/$tfile
14971         local file=$DIR/$tfile
14972
14973         free_min_max
14974         local cache_size=$(do_facet ost$((MAXI+1)) \
14975                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14976         local large_file_size=$((cache_size * 2))
14977
14978         echo "OSS cache size: $cache_size KB"
14979         echo "Large file size: $large_file_size KB"
14980
14981         [ $MAXV -le $large_file_size ] &&
14982                 skip_env "max available OST size needs > $large_file_size KB"
14983
14984         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14985
14986         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14987                 error "dd of=$temp bs=$large_file_size count=1k failed"
14988         cp $temp $file
14989         ls -lh $temp $file
14990         cancel_lru_locks osc
14991         cmp $temp $file || error "$temp $file differ"
14992
14993         rm -f $temp $file
14994         true
14995 }
14996
14997 save_writethrough() {
14998         local facets=$(get_facets OST)
14999
15000         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15001 }
15002
15003 test_155a() {
15004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15005
15006         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15007
15008         save_writethrough $p
15009
15010         set_cache read on
15011         set_cache writethrough on
15012         test_155_small_load
15013         restore_lustre_params < $p
15014         rm -f $p
15015 }
15016 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15017
15018 test_155b() {
15019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15020
15021         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15022
15023         save_writethrough $p
15024
15025         set_cache read on
15026         set_cache writethrough off
15027         test_155_small_load
15028         restore_lustre_params < $p
15029         rm -f $p
15030 }
15031 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15032
15033 test_155c() {
15034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15035
15036         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15037
15038         save_writethrough $p
15039
15040         set_cache read off
15041         set_cache writethrough on
15042         test_155_small_load
15043         restore_lustre_params < $p
15044         rm -f $p
15045 }
15046 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15047
15048 test_155d() {
15049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15050
15051         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15052
15053         save_writethrough $p
15054
15055         set_cache read off
15056         set_cache writethrough off
15057         test_155_small_load
15058         restore_lustre_params < $p
15059         rm -f $p
15060 }
15061 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15062
15063 test_155e() {
15064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15065
15066         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15067
15068         save_writethrough $p
15069
15070         set_cache read on
15071         set_cache writethrough on
15072         test_155_big_load
15073         restore_lustre_params < $p
15074         rm -f $p
15075 }
15076 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15077
15078 test_155f() {
15079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15080
15081         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15082
15083         save_writethrough $p
15084
15085         set_cache read on
15086         set_cache writethrough off
15087         test_155_big_load
15088         restore_lustre_params < $p
15089         rm -f $p
15090 }
15091 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15092
15093 test_155g() {
15094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15095
15096         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15097
15098         save_writethrough $p
15099
15100         set_cache read off
15101         set_cache writethrough on
15102         test_155_big_load
15103         restore_lustre_params < $p
15104         rm -f $p
15105 }
15106 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15107
15108 test_155h() {
15109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15110
15111         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15112
15113         save_writethrough $p
15114
15115         set_cache read off
15116         set_cache writethrough off
15117         test_155_big_load
15118         restore_lustre_params < $p
15119         rm -f $p
15120 }
15121 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15122
15123 test_156() {
15124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15125         remote_ost_nodsh && skip "remote OST with nodsh"
15126         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15127                 skip "stats not implemented on old servers"
15128         [ "$ost1_FSTYPE" = "zfs" ] &&
15129                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15130
15131         local CPAGES=3
15132         local BEFORE
15133         local AFTER
15134         local file="$DIR/$tfile"
15135         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15136
15137         save_writethrough $p
15138         roc_hit_init
15139
15140         log "Turn on read and write cache"
15141         set_cache read on
15142         set_cache writethrough on
15143
15144         log "Write data and read it back."
15145         log "Read should be satisfied from the cache."
15146         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15147         BEFORE=$(roc_hit)
15148         cancel_lru_locks osc
15149         cat $file >/dev/null
15150         AFTER=$(roc_hit)
15151         if ! let "AFTER - BEFORE == CPAGES"; then
15152                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15153         else
15154                 log "cache hits: before: $BEFORE, after: $AFTER"
15155         fi
15156
15157         log "Read again; it should be satisfied from the cache."
15158         BEFORE=$AFTER
15159         cancel_lru_locks osc
15160         cat $file >/dev/null
15161         AFTER=$(roc_hit)
15162         if ! let "AFTER - BEFORE == CPAGES"; then
15163                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15164         else
15165                 log "cache hits:: before: $BEFORE, after: $AFTER"
15166         fi
15167
15168         log "Turn off the read cache and turn on the write cache"
15169         set_cache read off
15170         set_cache writethrough on
15171
15172         log "Read again; it should be satisfied from the cache."
15173         BEFORE=$(roc_hit)
15174         cancel_lru_locks osc
15175         cat $file >/dev/null
15176         AFTER=$(roc_hit)
15177         if ! let "AFTER - BEFORE == CPAGES"; then
15178                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15179         else
15180                 log "cache hits:: before: $BEFORE, after: $AFTER"
15181         fi
15182
15183         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15184                 # > 2.12.56 uses pagecache if cached
15185                 log "Read again; it should not be satisfied from the cache."
15186                 BEFORE=$AFTER
15187                 cancel_lru_locks osc
15188                 cat $file >/dev/null
15189                 AFTER=$(roc_hit)
15190                 if ! let "AFTER - BEFORE == 0"; then
15191                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15192                 else
15193                         log "cache hits:: before: $BEFORE, after: $AFTER"
15194                 fi
15195         fi
15196
15197         log "Write data and read it back."
15198         log "Read should be satisfied from the cache."
15199         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15200         BEFORE=$(roc_hit)
15201         cancel_lru_locks osc
15202         cat $file >/dev/null
15203         AFTER=$(roc_hit)
15204         if ! let "AFTER - BEFORE == CPAGES"; then
15205                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15206         else
15207                 log "cache hits:: before: $BEFORE, after: $AFTER"
15208         fi
15209
15210         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15211                 # > 2.12.56 uses pagecache if cached
15212                 log "Read again; it should not be satisfied from the cache."
15213                 BEFORE=$AFTER
15214                 cancel_lru_locks osc
15215                 cat $file >/dev/null
15216                 AFTER=$(roc_hit)
15217                 if ! let "AFTER - BEFORE == 0"; then
15218                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15219                 else
15220                         log "cache hits:: before: $BEFORE, after: $AFTER"
15221                 fi
15222         fi
15223
15224         log "Turn off read and write cache"
15225         set_cache read off
15226         set_cache writethrough off
15227
15228         log "Write data and read it back"
15229         log "It should not be satisfied from the cache."
15230         rm -f $file
15231         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15232         cancel_lru_locks osc
15233         BEFORE=$(roc_hit)
15234         cat $file >/dev/null
15235         AFTER=$(roc_hit)
15236         if ! let "AFTER - BEFORE == 0"; then
15237                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15238         else
15239                 log "cache hits:: before: $BEFORE, after: $AFTER"
15240         fi
15241
15242         log "Turn on the read cache and turn off the write cache"
15243         set_cache read on
15244         set_cache writethrough off
15245
15246         log "Write data and read it back"
15247         log "It should not be satisfied from the cache."
15248         rm -f $file
15249         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15250         BEFORE=$(roc_hit)
15251         cancel_lru_locks osc
15252         cat $file >/dev/null
15253         AFTER=$(roc_hit)
15254         if ! let "AFTER - BEFORE == 0"; then
15255                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15256         else
15257                 log "cache hits:: before: $BEFORE, after: $AFTER"
15258         fi
15259
15260         log "Read again; it should be satisfied from the cache."
15261         BEFORE=$(roc_hit)
15262         cancel_lru_locks osc
15263         cat $file >/dev/null
15264         AFTER=$(roc_hit)
15265         if ! let "AFTER - BEFORE == CPAGES"; then
15266                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15267         else
15268                 log "cache hits:: before: $BEFORE, after: $AFTER"
15269         fi
15270
15271         restore_lustre_params < $p
15272         rm -f $p $file
15273 }
15274 run_test 156 "Verification of tunables"
15275
15276 test_160a() {
15277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15278         remote_mds_nodsh && skip "remote MDS with nodsh"
15279         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15280                 skip "Need MDS version at least 2.2.0"
15281
15282         changelog_register || error "changelog_register failed"
15283         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15284         changelog_users $SINGLEMDS | grep -q $cl_user ||
15285                 error "User $cl_user not found in changelog_users"
15286
15287         mkdir_on_mdt0 $DIR/$tdir
15288
15289         # change something
15290         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15291         changelog_clear 0 || error "changelog_clear failed"
15292         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15293         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15294         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15295         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15296         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15297         rm $DIR/$tdir/pics/desktop.jpg
15298
15299         changelog_dump | tail -10
15300
15301         echo "verifying changelog mask"
15302         changelog_chmask "-MKDIR"
15303         changelog_chmask "-CLOSE"
15304
15305         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15306         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15307
15308         changelog_chmask "+MKDIR"
15309         changelog_chmask "+CLOSE"
15310
15311         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15312         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15313
15314         changelog_dump | tail -10
15315         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15316         CLOSES=$(changelog_dump | grep -c "CLOSE")
15317         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15318         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15319
15320         # verify contents
15321         echo "verifying target fid"
15322         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15323         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15324         [ "$fidc" == "$fidf" ] ||
15325                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15326         echo "verifying parent fid"
15327         # The FID returned from the Changelog may be the directory shard on
15328         # a different MDT, and not the FID returned by path2fid on the parent.
15329         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15330         # since this is what will matter when recreating this file in the tree.
15331         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15332         local pathp=$($LFS fid2path $MOUNT "$fidp")
15333         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15334                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15335
15336         echo "getting records for $cl_user"
15337         changelog_users $SINGLEMDS
15338         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15339         local nclr=3
15340         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15341                 error "changelog_clear failed"
15342         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15343         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15344         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15345                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15346
15347         local min0_rec=$(changelog_users $SINGLEMDS |
15348                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15349         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15350                           awk '{ print $1; exit; }')
15351
15352         changelog_dump | tail -n 5
15353         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15354         [ $first_rec == $((min0_rec + 1)) ] ||
15355                 error "first index should be $min0_rec + 1 not $first_rec"
15356
15357         # LU-3446 changelog index reset on MDT restart
15358         local cur_rec1=$(changelog_users $SINGLEMDS |
15359                          awk '/^current.index:/ { print $NF }')
15360         changelog_clear 0 ||
15361                 error "clear all changelog records for $cl_user failed"
15362         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15363         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15364                 error "Fail to start $SINGLEMDS"
15365         local cur_rec2=$(changelog_users $SINGLEMDS |
15366                          awk '/^current.index:/ { print $NF }')
15367         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15368         [ $cur_rec1 == $cur_rec2 ] ||
15369                 error "current index should be $cur_rec1 not $cur_rec2"
15370
15371         echo "verifying users from this test are deregistered"
15372         changelog_deregister || error "changelog_deregister failed"
15373         changelog_users $SINGLEMDS | grep -q $cl_user &&
15374                 error "User '$cl_user' still in changelog_users"
15375
15376         # lctl get_param -n mdd.*.changelog_users
15377         # current index: 144
15378         # ID    index (idle seconds)
15379         # cl3   144 (2)
15380         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15381                 # this is the normal case where all users were deregistered
15382                 # make sure no new records are added when no users are present
15383                 local last_rec1=$(changelog_users $SINGLEMDS |
15384                                   awk '/^current.index:/ { print $NF }')
15385                 touch $DIR/$tdir/chloe
15386                 local last_rec2=$(changelog_users $SINGLEMDS |
15387                                   awk '/^current.index:/ { print $NF }')
15388                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15389                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15390         else
15391                 # any changelog users must be leftovers from a previous test
15392                 changelog_users $SINGLEMDS
15393                 echo "other changelog users; can't verify off"
15394         fi
15395 }
15396 run_test 160a "changelog sanity"
15397
15398 test_160b() { # LU-3587
15399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15400         remote_mds_nodsh && skip "remote MDS with nodsh"
15401         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15402                 skip "Need MDS version at least 2.2.0"
15403
15404         changelog_register || error "changelog_register failed"
15405         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15406         changelog_users $SINGLEMDS | grep -q $cl_user ||
15407                 error "User '$cl_user' not found in changelog_users"
15408
15409         local longname1=$(str_repeat a 255)
15410         local longname2=$(str_repeat b 255)
15411
15412         cd $DIR
15413         echo "creating very long named file"
15414         touch $longname1 || error "create of '$longname1' failed"
15415         echo "renaming very long named file"
15416         mv $longname1 $longname2
15417
15418         changelog_dump | grep RENME | tail -n 5
15419         rm -f $longname2
15420 }
15421 run_test 160b "Verify that very long rename doesn't crash in changelog"
15422
15423 test_160c() {
15424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15425         remote_mds_nodsh && skip "remote MDS with nodsh"
15426
15427         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15428                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15429                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15430                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15431
15432         local rc=0
15433
15434         # Registration step
15435         changelog_register || error "changelog_register failed"
15436
15437         rm -rf $DIR/$tdir
15438         mkdir -p $DIR/$tdir
15439         $MCREATE $DIR/$tdir/foo_160c
15440         changelog_chmask "-TRUNC"
15441         $TRUNCATE $DIR/$tdir/foo_160c 200
15442         changelog_chmask "+TRUNC"
15443         $TRUNCATE $DIR/$tdir/foo_160c 199
15444         changelog_dump | tail -n 5
15445         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15446         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15447 }
15448 run_test 160c "verify that changelog log catch the truncate event"
15449
15450 test_160d() {
15451         remote_mds_nodsh && skip "remote MDS with nodsh"
15452         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15454         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15455                 skip "Need MDS version at least 2.7.60"
15456
15457         # Registration step
15458         changelog_register || error "changelog_register failed"
15459
15460         mkdir -p $DIR/$tdir/migrate_dir
15461         changelog_clear 0 || error "changelog_clear failed"
15462
15463         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15464         changelog_dump | tail -n 5
15465         local migrates=$(changelog_dump | grep -c "MIGRT")
15466         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15467 }
15468 run_test 160d "verify that changelog log catch the migrate event"
15469
15470 test_160e() {
15471         remote_mds_nodsh && skip "remote MDS with nodsh"
15472
15473         # Create a user
15474         changelog_register || error "changelog_register failed"
15475
15476         # Delete a future user (expect fail)
15477         local MDT0=$(facet_svc $SINGLEMDS)
15478         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15479         local rc=$?
15480
15481         if [ $rc -eq 0 ]; then
15482                 error "Deleted non-existant user cl77"
15483         elif [ $rc -ne 2 ]; then
15484                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15485         fi
15486
15487         # Clear to a bad index (1 billion should be safe)
15488         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15489         rc=$?
15490
15491         if [ $rc -eq 0 ]; then
15492                 error "Successfully cleared to invalid CL index"
15493         elif [ $rc -ne 22 ]; then
15494                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15495         fi
15496 }
15497 run_test 160e "changelog negative testing (should return errors)"
15498
15499 test_160f() {
15500         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15501         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15502                 skip "Need MDS version at least 2.10.56"
15503
15504         local mdts=$(comma_list $(mdts_nodes))
15505
15506         # Create a user
15507         changelog_register || error "first changelog_register failed"
15508         changelog_register || error "second changelog_register failed"
15509         local cl_users
15510         declare -A cl_user1
15511         declare -A cl_user2
15512         local user_rec1
15513         local user_rec2
15514         local i
15515
15516         # generate some changelog records to accumulate on each MDT
15517         # use all_char because created files should be evenly distributed
15518         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15519                 error "test_mkdir $tdir failed"
15520         log "$(date +%s): creating first files"
15521         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15522                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15523                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15524         done
15525
15526         # check changelogs have been generated
15527         local start=$SECONDS
15528         local idle_time=$((MDSCOUNT * 5 + 5))
15529         local nbcl=$(changelog_dump | wc -l)
15530         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15531
15532         for param in "changelog_max_idle_time=$idle_time" \
15533                      "changelog_gc=1" \
15534                      "changelog_min_gc_interval=2" \
15535                      "changelog_min_free_cat_entries=3"; do
15536                 local MDT0=$(facet_svc $SINGLEMDS)
15537                 local var="${param%=*}"
15538                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15539
15540                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15541                 do_nodes $mdts $LCTL set_param mdd.*.$param
15542         done
15543
15544         # force cl_user2 to be idle (1st part), but also cancel the
15545         # cl_user1 records so that it is not evicted later in the test.
15546         local sleep1=$((idle_time / 2))
15547         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15548         sleep $sleep1
15549
15550         # simulate changelog catalog almost full
15551         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15552         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15553
15554         for i in $(seq $MDSCOUNT); do
15555                 cl_users=(${CL_USERS[mds$i]})
15556                 cl_user1[mds$i]="${cl_users[0]}"
15557                 cl_user2[mds$i]="${cl_users[1]}"
15558
15559                 [ -n "${cl_user1[mds$i]}" ] ||
15560                         error "mds$i: no user registered"
15561                 [ -n "${cl_user2[mds$i]}" ] ||
15562                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15563
15564                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15565                 [ -n "$user_rec1" ] ||
15566                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15567                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15568                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15569                 [ -n "$user_rec2" ] ||
15570                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15571                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15572                      "$user_rec1 + 2 == $user_rec2"
15573                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15574                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15575                               "$user_rec1 + 2, but is $user_rec2"
15576                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15577                 [ -n "$user_rec2" ] ||
15578                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15579                 [ $user_rec1 == $user_rec2 ] ||
15580                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15581                               "$user_rec1, but is $user_rec2"
15582         done
15583
15584         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15585         local sleep2=$((idle_time - (SECONDS - start) + 1))
15586         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15587         sleep $sleep2
15588
15589         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15590         # cl_user1 should be OK because it recently processed records.
15591         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15592         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15593                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15594                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15595         done
15596
15597         # ensure gc thread is done
15598         for i in $(mdts_nodes); do
15599                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15600                         error "$i: GC-thread not done"
15601         done
15602
15603         local first_rec
15604         for (( i = 1; i <= MDSCOUNT; i++ )); do
15605                 # check cl_user1 still registered
15606                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15607                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15608                 # check cl_user2 unregistered
15609                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15610                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15611
15612                 # check changelogs are present and starting at $user_rec1 + 1
15613                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15614                 [ -n "$user_rec1" ] ||
15615                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15616                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15617                             awk '{ print $1; exit; }')
15618
15619                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15620                 [ $((user_rec1 + 1)) == $first_rec ] ||
15621                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15622         done
15623 }
15624 run_test 160f "changelog garbage collect (timestamped users)"
15625
15626 test_160g() {
15627         remote_mds_nodsh && skip "remote MDS with nodsh"
15628         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15629                 skip "Need MDS version at least 2.10.56"
15630
15631         local mdts=$(comma_list $(mdts_nodes))
15632
15633         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15634         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15635
15636         # Create a user
15637         changelog_register || error "first changelog_register failed"
15638         changelog_register || error "second changelog_register failed"
15639         local cl_users
15640         declare -A cl_user1
15641         declare -A cl_user2
15642         local user_rec1
15643         local user_rec2
15644         local i
15645
15646         # generate some changelog records to accumulate on each MDT
15647         # use all_char because created files should be evenly distributed
15648         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15649                 error "test_mkdir $tdir failed"
15650         for ((i = 0; i < MDSCOUNT; i++)); do
15651                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15652                         error "create $DIR/$tdir/d$i.1 failed"
15653         done
15654
15655         # check changelogs have been generated
15656         local nbcl=$(changelog_dump | wc -l)
15657         (( $nbcl > 0 )) || error "no changelogs found"
15658
15659         # reduce the max_idle_indexes value to make sure we exceed it
15660         for param in "changelog_max_idle_indexes=1" \
15661                      "changelog_gc=1" \
15662                      "changelog_min_gc_interval=2" \
15663                      "changelog_min_free_cat_entries=3"; do
15664                 local MDT0=$(facet_svc $SINGLEMDS)
15665                 local var="${param%=*}"
15666                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15667
15668                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15669                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15670                         error "unable to set mdd.*.$param"
15671         done
15672
15673         # simulate changelog catalog almost full
15674         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15675         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15676
15677         local start=$SECONDS
15678         for i in $(seq $MDSCOUNT); do
15679                 cl_users=(${CL_USERS[mds$i]})
15680                 cl_user1[mds$i]="${cl_users[0]}"
15681                 cl_user2[mds$i]="${cl_users[1]}"
15682
15683                 [ -n "${cl_user1[mds$i]}" ] ||
15684                         error "mds$i: no user registered"
15685                 [ -n "${cl_user2[mds$i]}" ] ||
15686                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15687
15688                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15689                 [ -n "$user_rec1" ] ||
15690                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15691                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15692                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15693                 [ -n "$user_rec2" ] ||
15694                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15695                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15696                      "$user_rec1 + 2 == $user_rec2"
15697                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15698                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15699                               "$user_rec1 + 2, but is $user_rec2"
15700                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15701                 [ -n "$user_rec2" ] ||
15702                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15703                 [ $user_rec1 == $user_rec2 ] ||
15704                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15705                               "$user_rec1, but is $user_rec2"
15706         done
15707
15708         # ensure we are past the previous changelog_min_gc_interval set above
15709         local sleep2=$((start + 2 - SECONDS))
15710         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15711
15712         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15713         # cl_user1 should be OK because it recently processed records.
15714         for ((i = 0; i < MDSCOUNT; i++)); do
15715                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15716                         error "create $DIR/$tdir/d$i.3 failed"
15717         done
15718
15719         # ensure gc thread is done
15720         for i in $(mdts_nodes); do
15721                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15722                         error "$i: GC-thread not done"
15723         done
15724
15725         local first_rec
15726         for (( i = 1; i <= MDSCOUNT; i++ )); do
15727                 # check cl_user1 still registered
15728                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15729                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15730                 # check cl_user2 unregistered
15731                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15732                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15733
15734                 # check changelogs are present and starting at $user_rec1 + 1
15735                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15736                 [ -n "$user_rec1" ] ||
15737                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15738                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15739                             awk '{ print $1; exit; }')
15740
15741                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15742                 [ $((user_rec1 + 1)) == $first_rec ] ||
15743                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15744         done
15745 }
15746 run_test 160g "changelog garbage collect (old users)"
15747
15748 test_160h() {
15749         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15750         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15751                 skip "Need MDS version at least 2.10.56"
15752
15753         local mdts=$(comma_list $(mdts_nodes))
15754
15755         # Create a user
15756         changelog_register || error "first changelog_register failed"
15757         changelog_register || error "second changelog_register failed"
15758         local cl_users
15759         declare -A cl_user1
15760         declare -A cl_user2
15761         local user_rec1
15762         local user_rec2
15763         local i
15764
15765         # generate some changelog records to accumulate on each MDT
15766         # use all_char because created files should be evenly distributed
15767         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15768                 error "test_mkdir $tdir failed"
15769         for ((i = 0; i < MDSCOUNT; i++)); do
15770                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15771                         error "create $DIR/$tdir/d$i.1 failed"
15772         done
15773
15774         # check changelogs have been generated
15775         local nbcl=$(changelog_dump | wc -l)
15776         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15777
15778         for param in "changelog_max_idle_time=10" \
15779                      "changelog_gc=1" \
15780                      "changelog_min_gc_interval=2"; do
15781                 local MDT0=$(facet_svc $SINGLEMDS)
15782                 local var="${param%=*}"
15783                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15784
15785                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15786                 do_nodes $mdts $LCTL set_param mdd.*.$param
15787         done
15788
15789         # force cl_user2 to be idle (1st part)
15790         sleep 9
15791
15792         for i in $(seq $MDSCOUNT); do
15793                 cl_users=(${CL_USERS[mds$i]})
15794                 cl_user1[mds$i]="${cl_users[0]}"
15795                 cl_user2[mds$i]="${cl_users[1]}"
15796
15797                 [ -n "${cl_user1[mds$i]}" ] ||
15798                         error "mds$i: no user registered"
15799                 [ -n "${cl_user2[mds$i]}" ] ||
15800                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15801
15802                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15803                 [ -n "$user_rec1" ] ||
15804                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15805                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15806                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15807                 [ -n "$user_rec2" ] ||
15808                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15809                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15810                      "$user_rec1 + 2 == $user_rec2"
15811                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15812                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15813                               "$user_rec1 + 2, but is $user_rec2"
15814                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15815                 [ -n "$user_rec2" ] ||
15816                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15817                 [ $user_rec1 == $user_rec2 ] ||
15818                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15819                               "$user_rec1, but is $user_rec2"
15820         done
15821
15822         # force cl_user2 to be idle (2nd part) and to reach
15823         # changelog_max_idle_time
15824         sleep 2
15825
15826         # force each GC-thread start and block then
15827         # one per MDT/MDD, set fail_val accordingly
15828         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15829         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15830
15831         # generate more changelogs to trigger fail_loc
15832         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15833                 error "create $DIR/$tdir/${tfile}bis failed"
15834
15835         # stop MDT to stop GC-thread, should be done in back-ground as it will
15836         # block waiting for the thread to be released and exit
15837         declare -A stop_pids
15838         for i in $(seq $MDSCOUNT); do
15839                 stop mds$i &
15840                 stop_pids[mds$i]=$!
15841         done
15842
15843         for i in $(mdts_nodes); do
15844                 local facet
15845                 local nb=0
15846                 local facets=$(facets_up_on_host $i)
15847
15848                 for facet in ${facets//,/ }; do
15849                         if [[ $facet == mds* ]]; then
15850                                 nb=$((nb + 1))
15851                         fi
15852                 done
15853                 # ensure each MDS's gc threads are still present and all in "R"
15854                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15855                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15856                         error "$i: expected $nb GC-thread"
15857                 wait_update $i \
15858                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15859                         "R" 20 ||
15860                         error "$i: GC-thread not found in R-state"
15861                 # check umounts of each MDT on MDS have reached kthread_stop()
15862                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15863                         error "$i: expected $nb umount"
15864                 wait_update $i \
15865                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15866                         error "$i: umount not found in D-state"
15867         done
15868
15869         # release all GC-threads
15870         do_nodes $mdts $LCTL set_param fail_loc=0
15871
15872         # wait for MDT stop to complete
15873         for i in $(seq $MDSCOUNT); do
15874                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15875         done
15876
15877         # XXX
15878         # may try to check if any orphan changelog records are present
15879         # via ldiskfs/zfs and llog_reader...
15880
15881         # re-start/mount MDTs
15882         for i in $(seq $MDSCOUNT); do
15883                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15884                         error "Fail to start mds$i"
15885         done
15886
15887         local first_rec
15888         for i in $(seq $MDSCOUNT); do
15889                 # check cl_user1 still registered
15890                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15891                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15892                 # check cl_user2 unregistered
15893                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15894                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15895
15896                 # check changelogs are present and starting at $user_rec1 + 1
15897                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15898                 [ -n "$user_rec1" ] ||
15899                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15900                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15901                             awk '{ print $1; exit; }')
15902
15903                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15904                 [ $((user_rec1 + 1)) == $first_rec ] ||
15905                         error "mds$i: first index should be $user_rec1 + 1, " \
15906                               "but is $first_rec"
15907         done
15908 }
15909 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15910               "during mount"
15911
15912 test_160i() {
15913
15914         local mdts=$(comma_list $(mdts_nodes))
15915
15916         changelog_register || error "first changelog_register failed"
15917
15918         # generate some changelog records to accumulate on each MDT
15919         # use all_char because created files should be evenly distributed
15920         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15921                 error "test_mkdir $tdir failed"
15922         for ((i = 0; i < MDSCOUNT; i++)); do
15923                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15924                         error "create $DIR/$tdir/d$i.1 failed"
15925         done
15926
15927         # check changelogs have been generated
15928         local nbcl=$(changelog_dump | wc -l)
15929         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15930
15931         # simulate race between register and unregister
15932         # XXX as fail_loc is set per-MDS, with DNE configs the race
15933         # simulation will only occur for one MDT per MDS and for the
15934         # others the normal race scenario will take place
15935         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15936         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15937         do_nodes $mdts $LCTL set_param fail_val=1
15938
15939         # unregister 1st user
15940         changelog_deregister &
15941         local pid1=$!
15942         # wait some time for deregister work to reach race rdv
15943         sleep 2
15944         # register 2nd user
15945         changelog_register || error "2nd user register failed"
15946
15947         wait $pid1 || error "1st user deregister failed"
15948
15949         local i
15950         local last_rec
15951         declare -A LAST_REC
15952         for i in $(seq $MDSCOUNT); do
15953                 if changelog_users mds$i | grep "^cl"; then
15954                         # make sure new records are added with one user present
15955                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15956                                           awk '/^current.index:/ { print $NF }')
15957                 else
15958                         error "mds$i has no user registered"
15959                 fi
15960         done
15961
15962         # generate more changelog records to accumulate on each MDT
15963         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15964                 error "create $DIR/$tdir/${tfile}bis failed"
15965
15966         for i in $(seq $MDSCOUNT); do
15967                 last_rec=$(changelog_users $SINGLEMDS |
15968                            awk '/^current.index:/ { print $NF }')
15969                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15970                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15971                         error "changelogs are off on mds$i"
15972         done
15973 }
15974 run_test 160i "changelog user register/unregister race"
15975
15976 test_160j() {
15977         remote_mds_nodsh && skip "remote MDS with nodsh"
15978         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15979                 skip "Need MDS version at least 2.12.56"
15980
15981         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15982         stack_trap "umount $MOUNT2" EXIT
15983
15984         changelog_register || error "first changelog_register failed"
15985         stack_trap "changelog_deregister" EXIT
15986
15987         # generate some changelog
15988         # use all_char because created files should be evenly distributed
15989         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15990                 error "mkdir $tdir failed"
15991         for ((i = 0; i < MDSCOUNT; i++)); do
15992                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15993                         error "create $DIR/$tdir/d$i.1 failed"
15994         done
15995
15996         # open the changelog device
15997         exec 3>/dev/changelog-$FSNAME-MDT0000
15998         stack_trap "exec 3>&-" EXIT
15999         exec 4</dev/changelog-$FSNAME-MDT0000
16000         stack_trap "exec 4<&-" EXIT
16001
16002         # umount the first lustre mount
16003         umount $MOUNT
16004         stack_trap "mount_client $MOUNT" EXIT
16005
16006         # read changelog, which may or may not fail, but should not crash
16007         cat <&4 >/dev/null
16008
16009         # clear changelog
16010         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16011         changelog_users $SINGLEMDS | grep -q $cl_user ||
16012                 error "User $cl_user not found in changelog_users"
16013
16014         printf 'clear:'$cl_user':0' >&3
16015 }
16016 run_test 160j "client can be umounted while its chanangelog is being used"
16017
16018 test_160k() {
16019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16020         remote_mds_nodsh && skip "remote MDS with nodsh"
16021
16022         mkdir -p $DIR/$tdir/1/1
16023
16024         changelog_register || error "changelog_register failed"
16025         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16026
16027         changelog_users $SINGLEMDS | grep -q $cl_user ||
16028                 error "User '$cl_user' not found in changelog_users"
16029 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16030         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16031         rmdir $DIR/$tdir/1/1 & sleep 1
16032         mkdir $DIR/$tdir/2
16033         touch $DIR/$tdir/2/2
16034         rm -rf $DIR/$tdir/2
16035
16036         wait
16037         sleep 4
16038
16039         changelog_dump | grep rmdir || error "rmdir not recorded"
16040 }
16041 run_test 160k "Verify that changelog records are not lost"
16042
16043 # Verifies that a file passed as a parameter has recently had an operation
16044 # performed on it that has generated an MTIME changelog which contains the
16045 # correct parent FID. As files might reside on a different MDT from the
16046 # parent directory in DNE configurations, the FIDs are translated to paths
16047 # before being compared, which should be identical
16048 compare_mtime_changelog() {
16049         local file="${1}"
16050         local mdtidx
16051         local mtime
16052         local cl_fid
16053         local pdir
16054         local dir
16055
16056         mdtidx=$($LFS getstripe --mdt-index $file)
16057         mdtidx=$(printf "%04x" $mdtidx)
16058
16059         # Obtain the parent FID from the MTIME changelog
16060         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16061         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16062
16063         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16064         [ -z "$cl_fid" ] && error "parent FID not present"
16065
16066         # Verify that the path for the parent FID is the same as the path for
16067         # the test directory
16068         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16069
16070         dir=$(dirname $1)
16071
16072         [[ "${pdir%/}" == "$dir" ]] ||
16073                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16074 }
16075
16076 test_160l() {
16077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16078
16079         remote_mds_nodsh && skip "remote MDS with nodsh"
16080         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16081                 skip "Need MDS version at least 2.13.55"
16082
16083         local cl_user
16084
16085         changelog_register || error "changelog_register failed"
16086         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16087
16088         changelog_users $SINGLEMDS | grep -q $cl_user ||
16089                 error "User '$cl_user' not found in changelog_users"
16090
16091         # Clear some types so that MTIME changelogs are generated
16092         changelog_chmask "-CREAT"
16093         changelog_chmask "-CLOSE"
16094
16095         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16096
16097         # Test CL_MTIME during setattr
16098         touch $DIR/$tdir/$tfile
16099         compare_mtime_changelog $DIR/$tdir/$tfile
16100
16101         # Test CL_MTIME during close
16102         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16103         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16104 }
16105 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16106
16107 test_160m() {
16108         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16109         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16110                 skip "Need MDS version at least 2.14.51"
16111         local cl_users
16112         local cl_user1
16113         local cl_user2
16114         local pid1
16115
16116         # Create a user
16117         changelog_register || error "first changelog_register failed"
16118         changelog_register || error "second changelog_register failed"
16119
16120         cl_users=(${CL_USERS[mds1]})
16121         cl_user1="${cl_users[0]}"
16122         cl_user2="${cl_users[1]}"
16123         # generate some changelog records to accumulate on MDT0
16124         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16125         createmany -m $DIR/$tdir/$tfile 50 ||
16126                 error "create $DIR/$tdir/$tfile failed"
16127         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16128         rm -f $DIR/$tdir
16129
16130         # check changelogs have been generated
16131         local nbcl=$(changelog_dump | wc -l)
16132         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16133
16134 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16135         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16136
16137         __changelog_clear mds1 $cl_user1 +10
16138         __changelog_clear mds1 $cl_user2 0 &
16139         pid1=$!
16140         sleep 2
16141         __changelog_clear mds1 $cl_user1 0 ||
16142                 error "fail to cancel record for $cl_user1"
16143         wait $pid1
16144         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16145 }
16146 run_test 160m "Changelog clear race"
16147
16148 test_160n() {
16149         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16150         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16151                 skip "Need MDS version at least 2.14.51"
16152         local cl_users
16153         local cl_user1
16154         local cl_user2
16155         local pid1
16156         local first_rec
16157         local last_rec=0
16158
16159         # Create a user
16160         changelog_register || error "first changelog_register failed"
16161
16162         cl_users=(${CL_USERS[mds1]})
16163         cl_user1="${cl_users[0]}"
16164
16165         # generate some changelog records to accumulate on MDT0
16166         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16167         first_rec=$(changelog_users $SINGLEMDS |
16168                         awk '/^current.index:/ { print $NF }')
16169         while (( last_rec < (( first_rec + 65000)) )); do
16170                 createmany -m $DIR/$tdir/$tfile 10000 ||
16171                         error "create $DIR/$tdir/$tfile failed"
16172
16173                 for i in $(seq 0 10000); do
16174                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16175                                 > /dev/null
16176                 done
16177
16178                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16179                         error "unlinkmany failed unlink"
16180                 last_rec=$(changelog_users $SINGLEMDS |
16181                         awk '/^current.index:/ { print $NF }')
16182                 echo last record $last_rec
16183                 (( last_rec == 0 )) && error "no changelog found"
16184         done
16185
16186 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16187         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16188
16189         __changelog_clear mds1 $cl_user1 0 &
16190         pid1=$!
16191         sleep 2
16192         __changelog_clear mds1 $cl_user1 0 ||
16193                 error "fail to cancel record for $cl_user1"
16194         wait $pid1
16195         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16196 }
16197 run_test 160n "Changelog destroy race"
16198
16199 test_160p() {
16200         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16201         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16202                 skip "Need MDS version at least 2.14.51"
16203         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16204         local cl_users
16205         local cl_user1
16206         local entry_count
16207
16208         # Create a user
16209         changelog_register || error "first changelog_register failed"
16210
16211         cl_users=(${CL_USERS[mds1]})
16212         cl_user1="${cl_users[0]}"
16213
16214         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16215         createmany -m $DIR/$tdir/$tfile 50 ||
16216                 error "create $DIR/$tdir/$tfile failed"
16217         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16218         rm -rf $DIR/$tdir
16219
16220         # check changelogs have been generated
16221         entry_count=$(changelog_dump | wc -l)
16222         ((entry_count != 0)) || error "no changelog entries found"
16223
16224         # remove changelog_users and check that orphan entries are removed
16225         stop mds1
16226         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16227         start mds1 || error "cannot start mdt"
16228         entry_count=$(changelog_dump | wc -l)
16229         ((entry_count == 0)) ||
16230                 error "found $entry_count changelog entries, expected none"
16231 }
16232 run_test 160p "Changelog orphan cleanup with no users"
16233
16234 test_161a() {
16235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16236
16237         test_mkdir -c1 $DIR/$tdir
16238         cp /etc/hosts $DIR/$tdir/$tfile
16239         test_mkdir -c1 $DIR/$tdir/foo1
16240         test_mkdir -c1 $DIR/$tdir/foo2
16241         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16242         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16243         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16244         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16245         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16246         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16247                 $LFS fid2path $DIR $FID
16248                 error "bad link ea"
16249         fi
16250         # middle
16251         rm $DIR/$tdir/foo2/zachary
16252         # last
16253         rm $DIR/$tdir/foo2/thor
16254         # first
16255         rm $DIR/$tdir/$tfile
16256         # rename
16257         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16258         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16259                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16260         rm $DIR/$tdir/foo2/maggie
16261
16262         # overflow the EA
16263         local longname=$tfile.avg_len_is_thirty_two_
16264         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16265                 error_noexit 'failed to unlink many hardlinks'" EXIT
16266         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16267                 error "failed to hardlink many files"
16268         links=$($LFS fid2path $DIR $FID | wc -l)
16269         echo -n "${links}/1000 links in link EA"
16270         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16271 }
16272 run_test 161a "link ea sanity"
16273
16274 test_161b() {
16275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16276         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16277
16278         local MDTIDX=1
16279         local remote_dir=$DIR/$tdir/remote_dir
16280
16281         mkdir -p $DIR/$tdir
16282         $LFS mkdir -i $MDTIDX $remote_dir ||
16283                 error "create remote directory failed"
16284
16285         cp /etc/hosts $remote_dir/$tfile
16286         mkdir -p $remote_dir/foo1
16287         mkdir -p $remote_dir/foo2
16288         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16289         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16290         ln $remote_dir/$tfile $remote_dir/foo1/luna
16291         ln $remote_dir/$tfile $remote_dir/foo2/thor
16292
16293         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16294                      tr -d ']')
16295         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16296                 $LFS fid2path $DIR $FID
16297                 error "bad link ea"
16298         fi
16299         # middle
16300         rm $remote_dir/foo2/zachary
16301         # last
16302         rm $remote_dir/foo2/thor
16303         # first
16304         rm $remote_dir/$tfile
16305         # rename
16306         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16307         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16308         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16309                 $LFS fid2path $DIR $FID
16310                 error "bad link rename"
16311         fi
16312         rm $remote_dir/foo2/maggie
16313
16314         # overflow the EA
16315         local longname=filename_avg_len_is_thirty_two_
16316         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16317                 error "failed to hardlink many files"
16318         links=$($LFS fid2path $DIR $FID | wc -l)
16319         echo -n "${links}/1000 links in link EA"
16320         [[ ${links} -gt 60 ]] ||
16321                 error "expected at least 60 links in link EA"
16322         unlinkmany $remote_dir/foo2/$longname 1000 ||
16323         error "failed to unlink many hardlinks"
16324 }
16325 run_test 161b "link ea sanity under remote directory"
16326
16327 test_161c() {
16328         remote_mds_nodsh && skip "remote MDS with nodsh"
16329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16330         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16331                 skip "Need MDS version at least 2.1.5"
16332
16333         # define CLF_RENAME_LAST 0x0001
16334         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16335         changelog_register || error "changelog_register failed"
16336
16337         rm -rf $DIR/$tdir
16338         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16339         touch $DIR/$tdir/foo_161c
16340         touch $DIR/$tdir/bar_161c
16341         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16342         changelog_dump | grep RENME | tail -n 5
16343         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16344         changelog_clear 0 || error "changelog_clear failed"
16345         if [ x$flags != "x0x1" ]; then
16346                 error "flag $flags is not 0x1"
16347         fi
16348
16349         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16350         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16351         touch $DIR/$tdir/foo_161c
16352         touch $DIR/$tdir/bar_161c
16353         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16354         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16355         changelog_dump | grep RENME | tail -n 5
16356         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16357         changelog_clear 0 || error "changelog_clear failed"
16358         if [ x$flags != "x0x0" ]; then
16359                 error "flag $flags is not 0x0"
16360         fi
16361         echo "rename overwrite a target having nlink > 1," \
16362                 "changelog record has flags of $flags"
16363
16364         # rename doesn't overwrite a target (changelog flag 0x0)
16365         touch $DIR/$tdir/foo_161c
16366         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16367         changelog_dump | grep RENME | tail -n 5
16368         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16369         changelog_clear 0 || error "changelog_clear failed"
16370         if [ x$flags != "x0x0" ]; then
16371                 error "flag $flags is not 0x0"
16372         fi
16373         echo "rename doesn't overwrite a target," \
16374                 "changelog record has flags of $flags"
16375
16376         # define CLF_UNLINK_LAST 0x0001
16377         # unlink a file having nlink = 1 (changelog flag 0x1)
16378         rm -f $DIR/$tdir/foo2_161c
16379         changelog_dump | grep UNLNK | tail -n 5
16380         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16381         changelog_clear 0 || error "changelog_clear failed"
16382         if [ x$flags != "x0x1" ]; then
16383                 error "flag $flags is not 0x1"
16384         fi
16385         echo "unlink a file having nlink = 1," \
16386                 "changelog record has flags of $flags"
16387
16388         # unlink a file having nlink > 1 (changelog flag 0x0)
16389         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16390         rm -f $DIR/$tdir/foobar_161c
16391         changelog_dump | grep UNLNK | tail -n 5
16392         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16393         changelog_clear 0 || error "changelog_clear failed"
16394         if [ x$flags != "x0x0" ]; then
16395                 error "flag $flags is not 0x0"
16396         fi
16397         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16398 }
16399 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16400
16401 test_161d() {
16402         remote_mds_nodsh && skip "remote MDS with nodsh"
16403         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16404
16405         local pid
16406         local fid
16407
16408         changelog_register || error "changelog_register failed"
16409
16410         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16411         # interfer with $MOUNT/.lustre/fid/ access
16412         mkdir $DIR/$tdir
16413         [[ $? -eq 0 ]] || error "mkdir failed"
16414
16415         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16416         $LCTL set_param fail_loc=0x8000140c
16417         # 5s pause
16418         $LCTL set_param fail_val=5
16419
16420         # create file
16421         echo foofoo > $DIR/$tdir/$tfile &
16422         pid=$!
16423
16424         # wait for create to be delayed
16425         sleep 2
16426
16427         ps -p $pid
16428         [[ $? -eq 0 ]] || error "create should be blocked"
16429
16430         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16431         stack_trap "rm -f $tempfile"
16432         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16433         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16434         # some delay may occur during ChangeLog publishing and file read just
16435         # above, that could allow file write to happen finally
16436         [[ -s $tempfile ]] && echo "file should be empty"
16437
16438         $LCTL set_param fail_loc=0
16439
16440         wait $pid
16441         [[ $? -eq 0 ]] || error "create failed"
16442 }
16443 run_test 161d "create with concurrent .lustre/fid access"
16444
16445 check_path() {
16446         local expected="$1"
16447         shift
16448         local fid="$2"
16449
16450         local path
16451         path=$($LFS fid2path "$@")
16452         local rc=$?
16453
16454         if [ $rc -ne 0 ]; then
16455                 error "path looked up of '$expected' failed: rc=$rc"
16456         elif [ "$path" != "$expected" ]; then
16457                 error "path looked up '$path' instead of '$expected'"
16458         else
16459                 echo "FID '$fid' resolves to path '$path' as expected"
16460         fi
16461 }
16462
16463 test_162a() { # was test_162
16464         test_mkdir -p -c1 $DIR/$tdir/d2
16465         touch $DIR/$tdir/d2/$tfile
16466         touch $DIR/$tdir/d2/x1
16467         touch $DIR/$tdir/d2/x2
16468         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16469         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16470         # regular file
16471         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16472         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16473
16474         # softlink
16475         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16476         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16477         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16478
16479         # softlink to wrong file
16480         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16481         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16482         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16483
16484         # hardlink
16485         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16486         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16487         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16488         # fid2path dir/fsname should both work
16489         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16490         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16491
16492         # hardlink count: check that there are 2 links
16493         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16494         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16495
16496         # hardlink indexing: remove the first link
16497         rm $DIR/$tdir/d2/p/q/r/hlink
16498         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16499 }
16500 run_test 162a "path lookup sanity"
16501
16502 test_162b() {
16503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16504         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16505
16506         mkdir $DIR/$tdir
16507         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16508                                 error "create striped dir failed"
16509
16510         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16511                                         tail -n 1 | awk '{print $2}')
16512         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16513
16514         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16515         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16516
16517         # regular file
16518         for ((i=0;i<5;i++)); do
16519                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16520                         error "get fid for f$i failed"
16521                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16522
16523                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16524                         error "get fid for d$i failed"
16525                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16526         done
16527
16528         return 0
16529 }
16530 run_test 162b "striped directory path lookup sanity"
16531
16532 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16533 test_162c() {
16534         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16535                 skip "Need MDS version at least 2.7.51"
16536
16537         local lpath=$tdir.local
16538         local rpath=$tdir.remote
16539
16540         test_mkdir $DIR/$lpath
16541         test_mkdir $DIR/$rpath
16542
16543         for ((i = 0; i <= 101; i++)); do
16544                 lpath="$lpath/$i"
16545                 mkdir $DIR/$lpath
16546                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16547                         error "get fid for local directory $DIR/$lpath failed"
16548                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16549
16550                 rpath="$rpath/$i"
16551                 test_mkdir $DIR/$rpath
16552                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16553                         error "get fid for remote directory $DIR/$rpath failed"
16554                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16555         done
16556
16557         return 0
16558 }
16559 run_test 162c "fid2path works with paths 100 or more directories deep"
16560
16561 oalr_event_count() {
16562         local event="${1}"
16563         local trace="${2}"
16564
16565         awk -v name="${FSNAME}-OST0000" \
16566             -v event="${event}" \
16567             '$1 == "TRACE" && $2 == event && $3 == name' \
16568             "${trace}" |
16569         wc -l
16570 }
16571
16572 oalr_expect_event_count() {
16573         local event="${1}"
16574         local trace="${2}"
16575         local expect="${3}"
16576         local count
16577
16578         count=$(oalr_event_count "${event}" "${trace}")
16579         if ((count == expect)); then
16580                 return 0
16581         fi
16582
16583         error_noexit "${event} event count was '${count}', expected ${expect}"
16584         cat "${trace}" >&2
16585         exit 1
16586 }
16587
16588 cleanup_165() {
16589         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16590         stop ost1
16591         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16592 }
16593
16594 setup_165() {
16595         sync # Flush previous IOs so we can count log entries.
16596         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16597         stack_trap cleanup_165 EXIT
16598 }
16599
16600 test_165a() {
16601         local trace="/tmp/${tfile}.trace"
16602         local rc
16603         local count
16604
16605         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16606                 skip "OFD access log unsupported"
16607
16608         setup_165
16609         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16610         sleep 5
16611
16612         do_facet ost1 ofd_access_log_reader --list
16613         stop ost1
16614
16615         do_facet ost1 killall -TERM ofd_access_log_reader
16616         wait
16617         rc=$?
16618
16619         if ((rc != 0)); then
16620                 error "ofd_access_log_reader exited with rc = '${rc}'"
16621         fi
16622
16623         # Parse trace file for discovery events:
16624         oalr_expect_event_count alr_log_add "${trace}" 1
16625         oalr_expect_event_count alr_log_eof "${trace}" 1
16626         oalr_expect_event_count alr_log_free "${trace}" 1
16627 }
16628 run_test 165a "ofd access log discovery"
16629
16630 test_165b() {
16631         local trace="/tmp/${tfile}.trace"
16632         local file="${DIR}/${tfile}"
16633         local pfid1
16634         local pfid2
16635         local -a entry
16636         local rc
16637         local count
16638         local size
16639         local flags
16640
16641         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16642                 skip "OFD access log unsupported"
16643
16644         setup_165
16645         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16646         sleep 5
16647
16648         do_facet ost1 ofd_access_log_reader --list
16649
16650         lfs setstripe -c 1 -i 0 "${file}"
16651         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16652                 error "cannot create '${file}'"
16653
16654         sleep 5
16655         do_facet ost1 killall -TERM ofd_access_log_reader
16656         wait
16657         rc=$?
16658
16659         if ((rc != 0)); then
16660                 error "ofd_access_log_reader exited with rc = '${rc}'"
16661         fi
16662
16663         oalr_expect_event_count alr_log_entry "${trace}" 1
16664
16665         pfid1=$($LFS path2fid "${file}")
16666
16667         # 1     2             3   4    5     6   7    8    9     10
16668         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16669         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16670
16671         echo "entry = '${entry[*]}'" >&2
16672
16673         pfid2=${entry[4]}
16674         if [[ "${pfid1}" != "${pfid2}" ]]; then
16675                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16676         fi
16677
16678         size=${entry[8]}
16679         if ((size != 1048576)); then
16680                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16681         fi
16682
16683         flags=${entry[10]}
16684         if [[ "${flags}" != "w" ]]; then
16685                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16686         fi
16687
16688         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16689         sleep 5
16690
16691         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16692                 error "cannot read '${file}'"
16693         sleep 5
16694
16695         do_facet ost1 killall -TERM ofd_access_log_reader
16696         wait
16697         rc=$?
16698
16699         if ((rc != 0)); then
16700                 error "ofd_access_log_reader exited with rc = '${rc}'"
16701         fi
16702
16703         oalr_expect_event_count alr_log_entry "${trace}" 1
16704
16705         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16706         echo "entry = '${entry[*]}'" >&2
16707
16708         pfid2=${entry[4]}
16709         if [[ "${pfid1}" != "${pfid2}" ]]; then
16710                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16711         fi
16712
16713         size=${entry[8]}
16714         if ((size != 524288)); then
16715                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16716         fi
16717
16718         flags=${entry[10]}
16719         if [[ "${flags}" != "r" ]]; then
16720                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16721         fi
16722 }
16723 run_test 165b "ofd access log entries are produced and consumed"
16724
16725 test_165c() {
16726         local trace="/tmp/${tfile}.trace"
16727         local file="${DIR}/${tdir}/${tfile}"
16728
16729         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16730                 skip "OFD access log unsupported"
16731
16732         test_mkdir "${DIR}/${tdir}"
16733
16734         setup_165
16735         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16736         sleep 5
16737
16738         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16739
16740         # 4096 / 64 = 64. Create twice as many entries.
16741         for ((i = 0; i < 128; i++)); do
16742                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16743                         error "cannot create file"
16744         done
16745
16746         sync
16747
16748         do_facet ost1 killall -TERM ofd_access_log_reader
16749         wait
16750         rc=$?
16751         if ((rc != 0)); then
16752                 error "ofd_access_log_reader exited with rc = '${rc}'"
16753         fi
16754
16755         unlinkmany  "${file}-%d" 128
16756 }
16757 run_test 165c "full ofd access logs do not block IOs"
16758
16759 oal_get_read_count() {
16760         local stats="$1"
16761
16762         # STATS lustre-OST0001 alr_read_count 1
16763
16764         do_facet ost1 cat "${stats}" |
16765         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16766              END { print count; }'
16767 }
16768
16769 oal_expect_read_count() {
16770         local stats="$1"
16771         local count
16772         local expect="$2"
16773
16774         # Ask ofd_access_log_reader to write stats.
16775         do_facet ost1 killall -USR1 ofd_access_log_reader
16776
16777         # Allow some time for things to happen.
16778         sleep 1
16779
16780         count=$(oal_get_read_count "${stats}")
16781         if ((count == expect)); then
16782                 return 0
16783         fi
16784
16785         error_noexit "bad read count, got ${count}, expected ${expect}"
16786         do_facet ost1 cat "${stats}" >&2
16787         exit 1
16788 }
16789
16790 test_165d() {
16791         local stats="/tmp/${tfile}.stats"
16792         local file="${DIR}/${tdir}/${tfile}"
16793         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16794
16795         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16796                 skip "OFD access log unsupported"
16797
16798         test_mkdir "${DIR}/${tdir}"
16799
16800         setup_165
16801         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16802         sleep 5
16803
16804         lfs setstripe -c 1 -i 0 "${file}"
16805
16806         do_facet ost1 lctl set_param "${param}=rw"
16807         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16808                 error "cannot create '${file}'"
16809         oal_expect_read_count "${stats}" 1
16810
16811         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16812                 error "cannot read '${file}'"
16813         oal_expect_read_count "${stats}" 2
16814
16815         do_facet ost1 lctl set_param "${param}=r"
16816         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16817                 error "cannot create '${file}'"
16818         oal_expect_read_count "${stats}" 2
16819
16820         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16821                 error "cannot read '${file}'"
16822         oal_expect_read_count "${stats}" 3
16823
16824         do_facet ost1 lctl set_param "${param}=w"
16825         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16826                 error "cannot create '${file}'"
16827         oal_expect_read_count "${stats}" 4
16828
16829         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16830                 error "cannot read '${file}'"
16831         oal_expect_read_count "${stats}" 4
16832
16833         do_facet ost1 lctl set_param "${param}=0"
16834         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16835                 error "cannot create '${file}'"
16836         oal_expect_read_count "${stats}" 4
16837
16838         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16839                 error "cannot read '${file}'"
16840         oal_expect_read_count "${stats}" 4
16841
16842         do_facet ost1 killall -TERM ofd_access_log_reader
16843         wait
16844         rc=$?
16845         if ((rc != 0)); then
16846                 error "ofd_access_log_reader exited with rc = '${rc}'"
16847         fi
16848 }
16849 run_test 165d "ofd_access_log mask works"
16850
16851 test_165e() {
16852         local stats="/tmp/${tfile}.stats"
16853         local file0="${DIR}/${tdir}-0/${tfile}"
16854         local file1="${DIR}/${tdir}-1/${tfile}"
16855
16856         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16857                 skip "OFD access log unsupported"
16858
16859         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16860
16861         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16862         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16863
16864         lfs setstripe -c 1 -i 0 "${file0}"
16865         lfs setstripe -c 1 -i 0 "${file1}"
16866
16867         setup_165
16868         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16869         sleep 5
16870
16871         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16872                 error "cannot create '${file0}'"
16873         sync
16874         oal_expect_read_count "${stats}" 0
16875
16876         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16877                 error "cannot create '${file1}'"
16878         sync
16879         oal_expect_read_count "${stats}" 1
16880
16881         do_facet ost1 killall -TERM ofd_access_log_reader
16882         wait
16883         rc=$?
16884         if ((rc != 0)); then
16885                 error "ofd_access_log_reader exited with rc = '${rc}'"
16886         fi
16887 }
16888 run_test 165e "ofd_access_log MDT index filter works"
16889
16890 test_165f() {
16891         local trace="/tmp/${tfile}.trace"
16892         local rc
16893         local count
16894
16895         setup_165
16896         do_facet ost1 timeout 60 ofd_access_log_reader \
16897                 --exit-on-close --debug=- --trace=- > "${trace}" &
16898         sleep 5
16899         stop ost1
16900
16901         wait
16902         rc=$?
16903
16904         if ((rc != 0)); then
16905                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16906                 cat "${trace}"
16907                 exit 1
16908         fi
16909 }
16910 run_test 165f "ofd_access_log_reader --exit-on-close works"
16911
16912 test_169() {
16913         # do directio so as not to populate the page cache
16914         log "creating a 10 Mb file"
16915         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16916                 error "multiop failed while creating a file"
16917         log "starting reads"
16918         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16919         log "truncating the file"
16920         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16921                 error "multiop failed while truncating the file"
16922         log "killing dd"
16923         kill %+ || true # reads might have finished
16924         echo "wait until dd is finished"
16925         wait
16926         log "removing the temporary file"
16927         rm -rf $DIR/$tfile || error "tmp file removal failed"
16928 }
16929 run_test 169 "parallel read and truncate should not deadlock"
16930
16931 test_170() {
16932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16933
16934         $LCTL clear     # bug 18514
16935         $LCTL debug_daemon start $TMP/${tfile}_log_good
16936         touch $DIR/$tfile
16937         $LCTL debug_daemon stop
16938         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16939                 error "sed failed to read log_good"
16940
16941         $LCTL debug_daemon start $TMP/${tfile}_log_good
16942         rm -rf $DIR/$tfile
16943         $LCTL debug_daemon stop
16944
16945         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16946                error "lctl df log_bad failed"
16947
16948         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16949         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16950
16951         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16952         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16953
16954         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16955                 error "bad_line good_line1 good_line2 are empty"
16956
16957         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16958         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16959         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16960
16961         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16962         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16963         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16964
16965         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16966                 error "bad_line_new good_line_new are empty"
16967
16968         local expected_good=$((good_line1 + good_line2*2))
16969
16970         rm -f $TMP/${tfile}*
16971         # LU-231, short malformed line may not be counted into bad lines
16972         if [ $bad_line -ne $bad_line_new ] &&
16973                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16974                 error "expected $bad_line bad lines, but got $bad_line_new"
16975                 return 1
16976         fi
16977
16978         if [ $expected_good -ne $good_line_new ]; then
16979                 error "expected $expected_good good lines, but got $good_line_new"
16980                 return 2
16981         fi
16982         true
16983 }
16984 run_test 170 "test lctl df to handle corrupted log ====================="
16985
16986 test_171() { # bug20592
16987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16988
16989         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16990         $LCTL set_param fail_loc=0x50e
16991         $LCTL set_param fail_val=3000
16992         multiop_bg_pause $DIR/$tfile O_s || true
16993         local MULTIPID=$!
16994         kill -USR1 $MULTIPID
16995         # cause log dump
16996         sleep 3
16997         wait $MULTIPID
16998         if dmesg | grep "recursive fault"; then
16999                 error "caught a recursive fault"
17000         fi
17001         $LCTL set_param fail_loc=0
17002         true
17003 }
17004 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17005
17006 # it would be good to share it with obdfilter-survey/iokit-libecho code
17007 setup_obdecho_osc () {
17008         local rc=0
17009         local ost_nid=$1
17010         local obdfilter_name=$2
17011         echo "Creating new osc for $obdfilter_name on $ost_nid"
17012         # make sure we can find loopback nid
17013         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17014
17015         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17016                            ${obdfilter_name}_osc_UUID || rc=2; }
17017         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17018                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17019         return $rc
17020 }
17021
17022 cleanup_obdecho_osc () {
17023         local obdfilter_name=$1
17024         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17025         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17026         return 0
17027 }
17028
17029 obdecho_test() {
17030         local OBD=$1
17031         local node=$2
17032         local pages=${3:-64}
17033         local rc=0
17034         local id
17035
17036         local count=10
17037         local obd_size=$(get_obd_size $node $OBD)
17038         local page_size=$(get_page_size $node)
17039         if [[ -n "$obd_size" ]]; then
17040                 local new_count=$((obd_size / (pages * page_size / 1024)))
17041                 [[ $new_count -ge $count ]] || count=$new_count
17042         fi
17043
17044         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17045         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17046                            rc=2; }
17047         if [ $rc -eq 0 ]; then
17048             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17049             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17050         fi
17051         echo "New object id is $id"
17052         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17053                            rc=4; }
17054         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17055                            "test_brw $count w v $pages $id" || rc=4; }
17056         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17057                            rc=4; }
17058         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17059                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17060         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17061                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17062         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17063         return $rc
17064 }
17065
17066 test_180a() {
17067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17068
17069         if ! [ -d /sys/fs/lustre/echo_client ] &&
17070            ! module_loaded obdecho; then
17071                 load_module obdecho/obdecho &&
17072                         stack_trap "rmmod obdecho" EXIT ||
17073                         error "unable to load obdecho on client"
17074         fi
17075
17076         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17077         local host=$($LCTL get_param -n osc.$osc.import |
17078                      awk '/current_connection:/ { print $2 }' )
17079         local target=$($LCTL get_param -n osc.$osc.import |
17080                        awk '/target:/ { print $2 }' )
17081         target=${target%_UUID}
17082
17083         if [ -n "$target" ]; then
17084                 setup_obdecho_osc $host $target &&
17085                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17086                         { error "obdecho setup failed with $?"; return; }
17087
17088                 obdecho_test ${target}_osc client ||
17089                         error "obdecho_test failed on ${target}_osc"
17090         else
17091                 $LCTL get_param osc.$osc.import
17092                 error "there is no osc.$osc.import target"
17093         fi
17094 }
17095 run_test 180a "test obdecho on osc"
17096
17097 test_180b() {
17098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17099         remote_ost_nodsh && skip "remote OST with nodsh"
17100
17101         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17102                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17103                 error "failed to load module obdecho"
17104
17105         local target=$(do_facet ost1 $LCTL dl |
17106                        awk '/obdfilter/ { print $4; exit; }')
17107
17108         if [ -n "$target" ]; then
17109                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17110         else
17111                 do_facet ost1 $LCTL dl
17112                 error "there is no obdfilter target on ost1"
17113         fi
17114 }
17115 run_test 180b "test obdecho directly on obdfilter"
17116
17117 test_180c() { # LU-2598
17118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17119         remote_ost_nodsh && skip "remote OST with nodsh"
17120         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17121                 skip "Need MDS version at least 2.4.0"
17122
17123         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17124                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17125                 error "failed to load module obdecho"
17126
17127         local target=$(do_facet ost1 $LCTL dl |
17128                        awk '/obdfilter/ { print $4; exit; }')
17129
17130         if [ -n "$target" ]; then
17131                 local pages=16384 # 64MB bulk I/O RPC size
17132
17133                 obdecho_test "$target" ost1 "$pages" ||
17134                         error "obdecho_test with pages=$pages failed with $?"
17135         else
17136                 do_facet ost1 $LCTL dl
17137                 error "there is no obdfilter target on ost1"
17138         fi
17139 }
17140 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17141
17142 test_181() { # bug 22177
17143         test_mkdir $DIR/$tdir
17144         # create enough files to index the directory
17145         createmany -o $DIR/$tdir/foobar 4000
17146         # print attributes for debug purpose
17147         lsattr -d .
17148         # open dir
17149         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17150         MULTIPID=$!
17151         # remove the files & current working dir
17152         unlinkmany $DIR/$tdir/foobar 4000
17153         rmdir $DIR/$tdir
17154         kill -USR1 $MULTIPID
17155         wait $MULTIPID
17156         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17157         return 0
17158 }
17159 run_test 181 "Test open-unlinked dir ========================"
17160
17161 test_182() {
17162         local fcount=1000
17163         local tcount=10
17164
17165         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17166
17167         $LCTL set_param mdc.*.rpc_stats=clear
17168
17169         for (( i = 0; i < $tcount; i++ )) ; do
17170                 mkdir $DIR/$tdir/$i
17171         done
17172
17173         for (( i = 0; i < $tcount; i++ )) ; do
17174                 createmany -o $DIR/$tdir/$i/f- $fcount &
17175         done
17176         wait
17177
17178         for (( i = 0; i < $tcount; i++ )) ; do
17179                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17180         done
17181         wait
17182
17183         $LCTL get_param mdc.*.rpc_stats
17184
17185         rm -rf $DIR/$tdir
17186 }
17187 run_test 182 "Test parallel modify metadata operations ================"
17188
17189 test_183() { # LU-2275
17190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17191         remote_mds_nodsh && skip "remote MDS with nodsh"
17192         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17193                 skip "Need MDS version at least 2.3.56"
17194
17195         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17196         echo aaa > $DIR/$tdir/$tfile
17197
17198 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17199         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17200
17201         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17202         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17203
17204         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17205
17206         # Flush negative dentry cache
17207         touch $DIR/$tdir/$tfile
17208
17209         # We are not checking for any leaked references here, they'll
17210         # become evident next time we do cleanup with module unload.
17211         rm -rf $DIR/$tdir
17212 }
17213 run_test 183 "No crash or request leak in case of strange dispositions ========"
17214
17215 # test suite 184 is for LU-2016, LU-2017
17216 test_184a() {
17217         check_swap_layouts_support
17218
17219         dir0=$DIR/$tdir/$testnum
17220         test_mkdir -p -c1 $dir0
17221         ref1=/etc/passwd
17222         ref2=/etc/group
17223         file1=$dir0/f1
17224         file2=$dir0/f2
17225         $LFS setstripe -c1 $file1
17226         cp $ref1 $file1
17227         $LFS setstripe -c2 $file2
17228         cp $ref2 $file2
17229         gen1=$($LFS getstripe -g $file1)
17230         gen2=$($LFS getstripe -g $file2)
17231
17232         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17233         gen=$($LFS getstripe -g $file1)
17234         [[ $gen1 != $gen ]] ||
17235                 "Layout generation on $file1 does not change"
17236         gen=$($LFS getstripe -g $file2)
17237         [[ $gen2 != $gen ]] ||
17238                 "Layout generation on $file2 does not change"
17239
17240         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17241         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17242
17243         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17244 }
17245 run_test 184a "Basic layout swap"
17246
17247 test_184b() {
17248         check_swap_layouts_support
17249
17250         dir0=$DIR/$tdir/$testnum
17251         mkdir -p $dir0 || error "creating dir $dir0"
17252         file1=$dir0/f1
17253         file2=$dir0/f2
17254         file3=$dir0/f3
17255         dir1=$dir0/d1
17256         dir2=$dir0/d2
17257         mkdir $dir1 $dir2
17258         $LFS setstripe -c1 $file1
17259         $LFS setstripe -c2 $file2
17260         $LFS setstripe -c1 $file3
17261         chown $RUNAS_ID $file3
17262         gen1=$($LFS getstripe -g $file1)
17263         gen2=$($LFS getstripe -g $file2)
17264
17265         $LFS swap_layouts $dir1 $dir2 &&
17266                 error "swap of directories layouts should fail"
17267         $LFS swap_layouts $dir1 $file1 &&
17268                 error "swap of directory and file layouts should fail"
17269         $RUNAS $LFS swap_layouts $file1 $file2 &&
17270                 error "swap of file we cannot write should fail"
17271         $LFS swap_layouts $file1 $file3 &&
17272                 error "swap of file with different owner should fail"
17273         /bin/true # to clear error code
17274 }
17275 run_test 184b "Forbidden layout swap (will generate errors)"
17276
17277 test_184c() {
17278         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17279         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17280         check_swap_layouts_support
17281         check_swap_layout_no_dom $DIR
17282
17283         local dir0=$DIR/$tdir/$testnum
17284         mkdir -p $dir0 || error "creating dir $dir0"
17285
17286         local ref1=$dir0/ref1
17287         local ref2=$dir0/ref2
17288         local file1=$dir0/file1
17289         local file2=$dir0/file2
17290         # create a file large enough for the concurrent test
17291         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17292         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17293         echo "ref file size: ref1($(stat -c %s $ref1))," \
17294              "ref2($(stat -c %s $ref2))"
17295
17296         cp $ref2 $file2
17297         dd if=$ref1 of=$file1 bs=16k &
17298         local DD_PID=$!
17299
17300         # Make sure dd starts to copy file, but wait at most 5 seconds
17301         local loops=0
17302         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17303
17304         $LFS swap_layouts $file1 $file2
17305         local rc=$?
17306         wait $DD_PID
17307         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17308         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17309
17310         # how many bytes copied before swapping layout
17311         local copied=$(stat -c %s $file2)
17312         local remaining=$(stat -c %s $ref1)
17313         remaining=$((remaining - copied))
17314         echo "Copied $copied bytes before swapping layout..."
17315
17316         cmp -n $copied $file1 $ref2 | grep differ &&
17317                 error "Content mismatch [0, $copied) of ref2 and file1"
17318         cmp -n $copied $file2 $ref1 ||
17319                 error "Content mismatch [0, $copied) of ref1 and file2"
17320         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17321                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17322
17323         # clean up
17324         rm -f $ref1 $ref2 $file1 $file2
17325 }
17326 run_test 184c "Concurrent write and layout swap"
17327
17328 test_184d() {
17329         check_swap_layouts_support
17330         check_swap_layout_no_dom $DIR
17331         [ -z "$(which getfattr 2>/dev/null)" ] &&
17332                 skip_env "no getfattr command"
17333
17334         local file1=$DIR/$tdir/$tfile-1
17335         local file2=$DIR/$tdir/$tfile-2
17336         local file3=$DIR/$tdir/$tfile-3
17337         local lovea1
17338         local lovea2
17339
17340         mkdir -p $DIR/$tdir
17341         touch $file1 || error "create $file1 failed"
17342         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17343                 error "create $file2 failed"
17344         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17345                 error "create $file3 failed"
17346         lovea1=$(get_layout_param $file1)
17347
17348         $LFS swap_layouts $file2 $file3 ||
17349                 error "swap $file2 $file3 layouts failed"
17350         $LFS swap_layouts $file1 $file2 ||
17351                 error "swap $file1 $file2 layouts failed"
17352
17353         lovea2=$(get_layout_param $file2)
17354         echo "$lovea1"
17355         echo "$lovea2"
17356         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17357
17358         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17359         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17360 }
17361 run_test 184d "allow stripeless layouts swap"
17362
17363 test_184e() {
17364         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17365                 skip "Need MDS version at least 2.6.94"
17366         check_swap_layouts_support
17367         check_swap_layout_no_dom $DIR
17368         [ -z "$(which getfattr 2>/dev/null)" ] &&
17369                 skip_env "no getfattr command"
17370
17371         local file1=$DIR/$tdir/$tfile-1
17372         local file2=$DIR/$tdir/$tfile-2
17373         local file3=$DIR/$tdir/$tfile-3
17374         local lovea
17375
17376         mkdir -p $DIR/$tdir
17377         touch $file1 || error "create $file1 failed"
17378         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17379                 error "create $file2 failed"
17380         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17381                 error "create $file3 failed"
17382
17383         $LFS swap_layouts $file1 $file2 ||
17384                 error "swap $file1 $file2 layouts failed"
17385
17386         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17387         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17388
17389         echo 123 > $file1 || error "Should be able to write into $file1"
17390
17391         $LFS swap_layouts $file1 $file3 ||
17392                 error "swap $file1 $file3 layouts failed"
17393
17394         echo 123 > $file1 || error "Should be able to write into $file1"
17395
17396         rm -rf $file1 $file2 $file3
17397 }
17398 run_test 184e "Recreate layout after stripeless layout swaps"
17399
17400 test_184f() {
17401         # Create a file with name longer than sizeof(struct stat) ==
17402         # 144 to see if we can get chars from the file name to appear
17403         # in the returned striping. Note that 'f' == 0x66.
17404         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17405
17406         mkdir -p $DIR/$tdir
17407         mcreate $DIR/$tdir/$file
17408         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17409                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17410         fi
17411 }
17412 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17413
17414 test_185() { # LU-2441
17415         # LU-3553 - no volatile file support in old servers
17416         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17417                 skip "Need MDS version at least 2.3.60"
17418
17419         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17420         touch $DIR/$tdir/spoo
17421         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17422         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17423                 error "cannot create/write a volatile file"
17424         [ "$FILESET" == "" ] &&
17425         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17426                 error "FID is still valid after close"
17427
17428         multiop_bg_pause $DIR/$tdir vVw4096_c
17429         local multi_pid=$!
17430
17431         local OLD_IFS=$IFS
17432         IFS=":"
17433         local fidv=($fid)
17434         IFS=$OLD_IFS
17435         # assume that the next FID for this client is sequential, since stdout
17436         # is unfortunately eaten by multiop_bg_pause
17437         local n=$((${fidv[1]} + 1))
17438         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17439         if [ "$FILESET" == "" ]; then
17440                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17441                         error "FID is missing before close"
17442         fi
17443         kill -USR1 $multi_pid
17444         # 1 second delay, so if mtime change we will see it
17445         sleep 1
17446         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17447         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17448 }
17449 run_test 185 "Volatile file support"
17450
17451 function create_check_volatile() {
17452         local idx=$1
17453         local tgt
17454
17455         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17456         local PID=$!
17457         sleep 1
17458         local FID=$(cat /tmp/${tfile}.fid)
17459         [ "$FID" == "" ] && error "can't get FID for volatile"
17460         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17461         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17462         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17463         kill -USR1 $PID
17464         wait
17465         sleep 1
17466         cancel_lru_locks mdc # flush opencache
17467         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17468         return 0
17469 }
17470
17471 test_185a(){
17472         # LU-12516 - volatile creation via .lustre
17473         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17474                 skip "Need MDS version at least 2.3.55"
17475
17476         create_check_volatile 0
17477         [ $MDSCOUNT -lt 2 ] && return 0
17478
17479         # DNE case
17480         create_check_volatile 1
17481
17482         return 0
17483 }
17484 run_test 185a "Volatile file creation in .lustre/fid/"
17485
17486 test_187a() {
17487         remote_mds_nodsh && skip "remote MDS with nodsh"
17488         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17489                 skip "Need MDS version at least 2.3.0"
17490
17491         local dir0=$DIR/$tdir/$testnum
17492         mkdir -p $dir0 || error "creating dir $dir0"
17493
17494         local file=$dir0/file1
17495         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17496         local dv1=$($LFS data_version $file)
17497         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17498         local dv2=$($LFS data_version $file)
17499         [[ $dv1 != $dv2 ]] ||
17500                 error "data version did not change on write $dv1 == $dv2"
17501
17502         # clean up
17503         rm -f $file1
17504 }
17505 run_test 187a "Test data version change"
17506
17507 test_187b() {
17508         remote_mds_nodsh && skip "remote MDS with nodsh"
17509         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17510                 skip "Need MDS version at least 2.3.0"
17511
17512         local dir0=$DIR/$tdir/$testnum
17513         mkdir -p $dir0 || error "creating dir $dir0"
17514
17515         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17516         [[ ${DV[0]} != ${DV[1]} ]] ||
17517                 error "data version did not change on write"\
17518                       " ${DV[0]} == ${DV[1]}"
17519
17520         # clean up
17521         rm -f $file1
17522 }
17523 run_test 187b "Test data version change on volatile file"
17524
17525 test_200() {
17526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17527         remote_mgs_nodsh && skip "remote MGS with nodsh"
17528         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17529
17530         local POOL=${POOL:-cea1}
17531         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17532         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17533         # Pool OST targets
17534         local first_ost=0
17535         local last_ost=$(($OSTCOUNT - 1))
17536         local ost_step=2
17537         local ost_list=$(seq $first_ost $ost_step $last_ost)
17538         local ost_range="$first_ost $last_ost $ost_step"
17539         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17540         local file_dir=$POOL_ROOT/file_tst
17541         local subdir=$test_path/subdir
17542         local rc=0
17543
17544         while : ; do
17545                 # former test_200a test_200b
17546                 pool_add $POOL                          || { rc=$? ; break; }
17547                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17548                 # former test_200c test_200d
17549                 mkdir -p $test_path
17550                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17551                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17552                 mkdir -p $subdir
17553                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17554                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17555                                                         || { rc=$? ; break; }
17556                 # former test_200e test_200f
17557                 local files=$((OSTCOUNT*3))
17558                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17559                                                         || { rc=$? ; break; }
17560                 pool_create_files $POOL $file_dir $files "$ost_list" \
17561                                                         || { rc=$? ; break; }
17562                 # former test_200g test_200h
17563                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17564                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17565
17566                 # former test_201a test_201b test_201c
17567                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17568
17569                 local f=$test_path/$tfile
17570                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17571                 pool_remove $POOL $f                    || { rc=$? ; break; }
17572                 break
17573         done
17574
17575         destroy_test_pools
17576
17577         return $rc
17578 }
17579 run_test 200 "OST pools"
17580
17581 # usage: default_attr <count | size | offset>
17582 default_attr() {
17583         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17584 }
17585
17586 # usage: check_default_stripe_attr
17587 check_default_stripe_attr() {
17588         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17589         case $1 in
17590         --stripe-count|-c)
17591                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17592         --stripe-size|-S)
17593                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17594         --stripe-index|-i)
17595                 EXPECTED=-1;;
17596         *)
17597                 error "unknown getstripe attr '$1'"
17598         esac
17599
17600         [ $ACTUAL == $EXPECTED ] ||
17601                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17602 }
17603
17604 test_204a() {
17605         test_mkdir $DIR/$tdir
17606         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17607
17608         check_default_stripe_attr --stripe-count
17609         check_default_stripe_attr --stripe-size
17610         check_default_stripe_attr --stripe-index
17611 }
17612 run_test 204a "Print default stripe attributes"
17613
17614 test_204b() {
17615         test_mkdir $DIR/$tdir
17616         $LFS setstripe --stripe-count 1 $DIR/$tdir
17617
17618         check_default_stripe_attr --stripe-size
17619         check_default_stripe_attr --stripe-index
17620 }
17621 run_test 204b "Print default stripe size and offset"
17622
17623 test_204c() {
17624         test_mkdir $DIR/$tdir
17625         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17626
17627         check_default_stripe_attr --stripe-count
17628         check_default_stripe_attr --stripe-index
17629 }
17630 run_test 204c "Print default stripe count and offset"
17631
17632 test_204d() {
17633         test_mkdir $DIR/$tdir
17634         $LFS setstripe --stripe-index 0 $DIR/$tdir
17635
17636         check_default_stripe_attr --stripe-count
17637         check_default_stripe_attr --stripe-size
17638 }
17639 run_test 204d "Print default stripe count and size"
17640
17641 test_204e() {
17642         test_mkdir $DIR/$tdir
17643         $LFS setstripe -d $DIR/$tdir
17644
17645         check_default_stripe_attr --stripe-count --raw
17646         check_default_stripe_attr --stripe-size --raw
17647         check_default_stripe_attr --stripe-index --raw
17648 }
17649 run_test 204e "Print raw stripe attributes"
17650
17651 test_204f() {
17652         test_mkdir $DIR/$tdir
17653         $LFS setstripe --stripe-count 1 $DIR/$tdir
17654
17655         check_default_stripe_attr --stripe-size --raw
17656         check_default_stripe_attr --stripe-index --raw
17657 }
17658 run_test 204f "Print raw stripe size and offset"
17659
17660 test_204g() {
17661         test_mkdir $DIR/$tdir
17662         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17663
17664         check_default_stripe_attr --stripe-count --raw
17665         check_default_stripe_attr --stripe-index --raw
17666 }
17667 run_test 204g "Print raw stripe count and offset"
17668
17669 test_204h() {
17670         test_mkdir $DIR/$tdir
17671         $LFS setstripe --stripe-index 0 $DIR/$tdir
17672
17673         check_default_stripe_attr --stripe-count --raw
17674         check_default_stripe_attr --stripe-size --raw
17675 }
17676 run_test 204h "Print raw stripe count and size"
17677
17678 # Figure out which job scheduler is being used, if any,
17679 # or use a fake one
17680 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17681         JOBENV=SLURM_JOB_ID
17682 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17683         JOBENV=LSB_JOBID
17684 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17685         JOBENV=PBS_JOBID
17686 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17687         JOBENV=LOADL_STEP_ID
17688 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17689         JOBENV=JOB_ID
17690 else
17691         $LCTL list_param jobid_name > /dev/null 2>&1
17692         if [ $? -eq 0 ]; then
17693                 JOBENV=nodelocal
17694         else
17695                 JOBENV=FAKE_JOBID
17696         fi
17697 fi
17698 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17699
17700 verify_jobstats() {
17701         local cmd=($1)
17702         shift
17703         local facets="$@"
17704
17705 # we don't really need to clear the stats for this test to work, since each
17706 # command has a unique jobid, but it makes debugging easier if needed.
17707 #       for facet in $facets; do
17708 #               local dev=$(convert_facet2label $facet)
17709 #               # clear old jobstats
17710 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17711 #       done
17712
17713         # use a new JobID for each test, or we might see an old one
17714         [ "$JOBENV" = "FAKE_JOBID" ] &&
17715                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17716
17717         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17718
17719         [ "$JOBENV" = "nodelocal" ] && {
17720                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17721                 $LCTL set_param jobid_name=$FAKE_JOBID
17722                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17723         }
17724
17725         log "Test: ${cmd[*]}"
17726         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17727
17728         if [ $JOBENV = "FAKE_JOBID" ]; then
17729                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17730         else
17731                 ${cmd[*]}
17732         fi
17733
17734         # all files are created on OST0000
17735         for facet in $facets; do
17736                 local stats="*.$(convert_facet2label $facet).job_stats"
17737
17738                 # strip out libtool wrappers for in-tree executables
17739                 if [ $(do_facet $facet lctl get_param $stats |
17740                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17741                         do_facet $facet lctl get_param $stats
17742                         error "No jobstats for $JOBVAL found on $facet::$stats"
17743                 fi
17744         done
17745 }
17746
17747 jobstats_set() {
17748         local new_jobenv=$1
17749
17750         set_persistent_param_and_check client "jobid_var" \
17751                 "$FSNAME.sys.jobid_var" $new_jobenv
17752 }
17753
17754 test_205a() { # Job stats
17755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17756         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17757                 skip "Need MDS version with at least 2.7.1"
17758         remote_mgs_nodsh && skip "remote MGS with nodsh"
17759         remote_mds_nodsh && skip "remote MDS with nodsh"
17760         remote_ost_nodsh && skip "remote OST with nodsh"
17761         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17762                 skip "Server doesn't support jobstats"
17763         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17764
17765         local old_jobenv=$($LCTL get_param -n jobid_var)
17766         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17767
17768         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17769                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17770         else
17771                 stack_trap "do_facet mgs $PERM_CMD \
17772                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17773         fi
17774         changelog_register
17775
17776         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17777                                 mdt.*.job_cleanup_interval | head -n 1)
17778         local new_interval=5
17779         do_facet $SINGLEMDS \
17780                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17781         stack_trap "do_facet $SINGLEMDS \
17782                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17783         local start=$SECONDS
17784
17785         local cmd
17786         # mkdir
17787         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
17788         verify_jobstats "$cmd" "$SINGLEMDS"
17789         # rmdir
17790         cmd="rmdir $DIR/$tdir"
17791         verify_jobstats "$cmd" "$SINGLEMDS"
17792         # mkdir on secondary MDT
17793         if [ $MDSCOUNT -gt 1 ]; then
17794                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17795                 verify_jobstats "$cmd" "mds2"
17796         fi
17797         # mknod
17798         cmd="mknod $DIR/$tfile c 1 3"
17799         verify_jobstats "$cmd" "$SINGLEMDS"
17800         # unlink
17801         cmd="rm -f $DIR/$tfile"
17802         verify_jobstats "$cmd" "$SINGLEMDS"
17803         # create all files on OST0000 so verify_jobstats can find OST stats
17804         # open & close
17805         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17806         verify_jobstats "$cmd" "$SINGLEMDS"
17807         # setattr
17808         cmd="touch $DIR/$tfile"
17809         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17810         # write
17811         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17812         verify_jobstats "$cmd" "ost1"
17813         # read
17814         cancel_lru_locks osc
17815         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17816         verify_jobstats "$cmd" "ost1"
17817         # truncate
17818         cmd="$TRUNCATE $DIR/$tfile 0"
17819         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17820         # rename
17821         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17822         verify_jobstats "$cmd" "$SINGLEMDS"
17823         # jobstats expiry - sleep until old stats should be expired
17824         local left=$((new_interval + 5 - (SECONDS - start)))
17825         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17826                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17827                         "0" $left
17828         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
17829         verify_jobstats "$cmd" "$SINGLEMDS"
17830         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17831             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17832
17833         # Ensure that jobid are present in changelog (if supported by MDS)
17834         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17835                 changelog_dump | tail -10
17836                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17837                 [ $jobids -eq 9 ] ||
17838                         error "Wrong changelog jobid count $jobids != 9"
17839
17840                 # LU-5862
17841                 JOBENV="disable"
17842                 jobstats_set $JOBENV
17843                 touch $DIR/$tfile
17844                 changelog_dump | grep $tfile
17845                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17846                 [ $jobids -eq 0 ] ||
17847                         error "Unexpected jobids when jobid_var=$JOBENV"
17848         fi
17849
17850         # test '%j' access to environment variable - if supported
17851         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17852                 JOBENV="JOBCOMPLEX"
17853                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17854
17855                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17856         fi
17857
17858         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17859                 JOBENV="JOBCOMPLEX"
17860                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17861
17862                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17863         fi
17864
17865         # test '%j' access to per-session jobid - if supported
17866         if lctl list_param jobid_this_session > /dev/null 2>&1
17867         then
17868                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17869                 lctl set_param jobid_this_session=$USER
17870
17871                 JOBENV="JOBCOMPLEX"
17872                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17873
17874                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17875         fi
17876 }
17877 run_test 205a "Verify job stats"
17878
17879 # LU-13117, LU-13597
17880 test_205b() {
17881         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
17882                 skip "Need MDS version at least 2.13.54.91"
17883
17884         job_stats="mdt.*.job_stats"
17885         $LCTL set_param $job_stats=clear
17886         # Setting jobid_var to USER might not be supported
17887         $LCTL set_param jobid_var=USER || true
17888         $LCTL set_param jobid_name="%e.%u"
17889         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17890         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17891                 grep "job_id:.*foolish" &&
17892                         error "Unexpected jobid found"
17893         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17894                 grep "open:.*min.*max.*sum" ||
17895                         error "wrong job_stats format found"
17896 }
17897 run_test 205b "Verify job stats jobid and output format"
17898
17899 # LU-13733
17900 test_205c() {
17901         $LCTL set_param llite.*.stats=0
17902         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17903         $LCTL get_param llite.*.stats
17904         $LCTL get_param llite.*.stats | grep \
17905                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17906                         error "wrong client stats format found"
17907 }
17908 run_test 205c "Verify client stats format"
17909
17910 # LU-1480, LU-1773 and LU-1657
17911 test_206() {
17912         mkdir -p $DIR/$tdir
17913         $LFS setstripe -c -1 $DIR/$tdir
17914 #define OBD_FAIL_LOV_INIT 0x1403
17915         $LCTL set_param fail_loc=0xa0001403
17916         $LCTL set_param fail_val=1
17917         touch $DIR/$tdir/$tfile || true
17918 }
17919 run_test 206 "fail lov_init_raid0() doesn't lbug"
17920
17921 test_207a() {
17922         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17923         local fsz=`stat -c %s $DIR/$tfile`
17924         cancel_lru_locks mdc
17925
17926         # do not return layout in getattr intent
17927 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17928         $LCTL set_param fail_loc=0x170
17929         local sz=`stat -c %s $DIR/$tfile`
17930
17931         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17932
17933         rm -rf $DIR/$tfile
17934 }
17935 run_test 207a "can refresh layout at glimpse"
17936
17937 test_207b() {
17938         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17939         local cksum=`md5sum $DIR/$tfile`
17940         local fsz=`stat -c %s $DIR/$tfile`
17941         cancel_lru_locks mdc
17942         cancel_lru_locks osc
17943
17944         # do not return layout in getattr intent
17945 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17946         $LCTL set_param fail_loc=0x171
17947
17948         # it will refresh layout after the file is opened but before read issues
17949         echo checksum is "$cksum"
17950         echo "$cksum" |md5sum -c --quiet || error "file differs"
17951
17952         rm -rf $DIR/$tfile
17953 }
17954 run_test 207b "can refresh layout at open"
17955
17956 test_208() {
17957         # FIXME: in this test suite, only RD lease is used. This is okay
17958         # for now as only exclusive open is supported. After generic lease
17959         # is done, this test suite should be revised. - Jinshan
17960
17961         remote_mds_nodsh && skip "remote MDS with nodsh"
17962         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17963                 skip "Need MDS version at least 2.4.52"
17964
17965         echo "==== test 1: verify get lease work"
17966         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17967
17968         echo "==== test 2: verify lease can be broken by upcoming open"
17969         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17970         local PID=$!
17971         sleep 1
17972
17973         $MULTIOP $DIR/$tfile oO_RDONLY:c
17974         kill -USR1 $PID && wait $PID || error "break lease error"
17975
17976         echo "==== test 3: verify lease can't be granted if an open already exists"
17977         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17978         local PID=$!
17979         sleep 1
17980
17981         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17982         kill -USR1 $PID && wait $PID || error "open file error"
17983
17984         echo "==== test 4: lease can sustain over recovery"
17985         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17986         PID=$!
17987         sleep 1
17988
17989         fail mds1
17990
17991         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17992
17993         echo "==== test 5: lease broken can't be regained by replay"
17994         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17995         PID=$!
17996         sleep 1
17997
17998         # open file to break lease and then recovery
17999         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18000         fail mds1
18001
18002         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18003
18004         rm -f $DIR/$tfile
18005 }
18006 run_test 208 "Exclusive open"
18007
18008 test_209() {
18009         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18010                 skip_env "must have disp_stripe"
18011
18012         touch $DIR/$tfile
18013         sync; sleep 5; sync;
18014
18015         echo 3 > /proc/sys/vm/drop_caches
18016         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18017                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18018         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18019
18020         # open/close 500 times
18021         for i in $(seq 500); do
18022                 cat $DIR/$tfile
18023         done
18024
18025         echo 3 > /proc/sys/vm/drop_caches
18026         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18027                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18028         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18029
18030         echo "before: $req_before, after: $req_after"
18031         [ $((req_after - req_before)) -ge 300 ] &&
18032                 error "open/close requests are not freed"
18033         return 0
18034 }
18035 run_test 209 "read-only open/close requests should be freed promptly"
18036
18037 test_210() {
18038         local pid
18039
18040         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18041         pid=$!
18042         sleep 1
18043
18044         $LFS getstripe $DIR/$tfile
18045         kill -USR1 $pid
18046         wait $pid || error "multiop failed"
18047
18048         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18049         pid=$!
18050         sleep 1
18051
18052         $LFS getstripe $DIR/$tfile
18053         kill -USR1 $pid
18054         wait $pid || error "multiop failed"
18055 }
18056 run_test 210 "lfs getstripe does not break leases"
18057
18058 test_212() {
18059         size=`date +%s`
18060         size=$((size % 8192 + 1))
18061         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18062         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18063         rm -f $DIR/f212 $DIR/f212.xyz
18064 }
18065 run_test 212 "Sendfile test ============================================"
18066
18067 test_213() {
18068         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18069         cancel_lru_locks osc
18070         lctl set_param fail_loc=0x8000040f
18071         # generate a read lock
18072         cat $DIR/$tfile > /dev/null
18073         # write to the file, it will try to cancel the above read lock.
18074         cat /etc/hosts >> $DIR/$tfile
18075 }
18076 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18077
18078 test_214() { # for bug 20133
18079         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18080         for (( i=0; i < 340; i++ )) ; do
18081                 touch $DIR/$tdir/d214c/a$i
18082         done
18083
18084         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18085         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18086         ls $DIR/d214c || error "ls $DIR/d214c failed"
18087         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18088         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18089 }
18090 run_test 214 "hash-indexed directory test - bug 20133"
18091
18092 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18093 create_lnet_proc_files() {
18094         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18095 }
18096
18097 # counterpart of create_lnet_proc_files
18098 remove_lnet_proc_files() {
18099         rm -f $TMP/lnet_$1.sys
18100 }
18101
18102 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18103 # 3rd arg as regexp for body
18104 check_lnet_proc_stats() {
18105         local l=$(cat "$TMP/lnet_$1" |wc -l)
18106         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18107
18108         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18109 }
18110
18111 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18112 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18113 # optional and can be regexp for 2nd line (lnet.routes case)
18114 check_lnet_proc_entry() {
18115         local blp=2          # blp stands for 'position of 1st line of body'
18116         [ -z "$5" ] || blp=3 # lnet.routes case
18117
18118         local l=$(cat "$TMP/lnet_$1" |wc -l)
18119         # subtracting one from $blp because the body can be empty
18120         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18121
18122         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18123                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18124
18125         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18126                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18127
18128         # bail out if any unexpected line happened
18129         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18130         [ "$?" != 0 ] || error "$2 misformatted"
18131 }
18132
18133 test_215() { # for bugs 18102, 21079, 21517
18134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18135
18136         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18137         local P='[1-9][0-9]*'           # positive numeric
18138         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18139         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18140         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18141         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18142
18143         local L1 # regexp for 1st line
18144         local L2 # regexp for 2nd line (optional)
18145         local BR # regexp for the rest (body)
18146
18147         # lnet.stats should look as 11 space-separated non-negative numerics
18148         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18149         create_lnet_proc_files "stats"
18150         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18151         remove_lnet_proc_files "stats"
18152
18153         # lnet.routes should look like this:
18154         # Routing disabled/enabled
18155         # net hops priority state router
18156         # where net is a string like tcp0, hops > 0, priority >= 0,
18157         # state is up/down,
18158         # router is a string like 192.168.1.1@tcp2
18159         L1="^Routing (disabled|enabled)$"
18160         L2="^net +hops +priority +state +router$"
18161         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18162         create_lnet_proc_files "routes"
18163         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18164         remove_lnet_proc_files "routes"
18165
18166         # lnet.routers should look like this:
18167         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18168         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18169         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18170         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18171         L1="^ref +rtr_ref +alive +router$"
18172         BR="^$P +$P +(up|down) +$NID$"
18173         create_lnet_proc_files "routers"
18174         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18175         remove_lnet_proc_files "routers"
18176
18177         # lnet.peers should look like this:
18178         # nid refs state last max rtr min tx min queue
18179         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18180         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18181         # numeric (0 or >0 or <0), queue >= 0.
18182         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18183         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18184         create_lnet_proc_files "peers"
18185         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18186         remove_lnet_proc_files "peers"
18187
18188         # lnet.buffers  should look like this:
18189         # pages count credits min
18190         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18191         L1="^pages +count +credits +min$"
18192         BR="^ +$N +$N +$I +$I$"
18193         create_lnet_proc_files "buffers"
18194         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18195         remove_lnet_proc_files "buffers"
18196
18197         # lnet.nis should look like this:
18198         # nid status alive refs peer rtr max tx min
18199         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18200         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18201         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18202         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18203         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18204         create_lnet_proc_files "nis"
18205         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18206         remove_lnet_proc_files "nis"
18207
18208         # can we successfully write to lnet.stats?
18209         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18210 }
18211 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18212
18213 test_216() { # bug 20317
18214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18215         remote_ost_nodsh && skip "remote OST with nodsh"
18216
18217         local node
18218         local facets=$(get_facets OST)
18219         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18220
18221         save_lustre_params client "osc.*.contention_seconds" > $p
18222         save_lustre_params $facets \
18223                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18224         save_lustre_params $facets \
18225                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18226         save_lustre_params $facets \
18227                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18228         clear_stats osc.*.osc_stats
18229
18230         # agressive lockless i/o settings
18231         do_nodes $(comma_list $(osts_nodes)) \
18232                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18233                         ldlm.namespaces.filter-*.contended_locks=0 \
18234                         ldlm.namespaces.filter-*.contention_seconds=60"
18235         lctl set_param -n osc.*.contention_seconds=60
18236
18237         $DIRECTIO write $DIR/$tfile 0 10 4096
18238         $CHECKSTAT -s 40960 $DIR/$tfile
18239
18240         # disable lockless i/o
18241         do_nodes $(comma_list $(osts_nodes)) \
18242                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18243                         ldlm.namespaces.filter-*.contended_locks=32 \
18244                         ldlm.namespaces.filter-*.contention_seconds=0"
18245         lctl set_param -n osc.*.contention_seconds=0
18246         clear_stats osc.*.osc_stats
18247
18248         dd if=/dev/zero of=$DIR/$tfile count=0
18249         $CHECKSTAT -s 0 $DIR/$tfile
18250
18251         restore_lustre_params <$p
18252         rm -f $p
18253         rm $DIR/$tfile
18254 }
18255 run_test 216 "check lockless direct write updates file size and kms correctly"
18256
18257 test_217() { # bug 22430
18258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18259
18260         local node
18261         local nid
18262
18263         for node in $(nodes_list); do
18264                 nid=$(host_nids_address $node $NETTYPE)
18265                 if [[ $nid = *-* ]] ; then
18266                         echo "lctl ping $(h2nettype $nid)"
18267                         lctl ping $(h2nettype $nid)
18268                 else
18269                         echo "skipping $node (no hyphen detected)"
18270                 fi
18271         done
18272 }
18273 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18274
18275 test_218() {
18276        # do directio so as not to populate the page cache
18277        log "creating a 10 Mb file"
18278        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18279        log "starting reads"
18280        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18281        log "truncating the file"
18282        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18283        log "killing dd"
18284        kill %+ || true # reads might have finished
18285        echo "wait until dd is finished"
18286        wait
18287        log "removing the temporary file"
18288        rm -rf $DIR/$tfile || error "tmp file removal failed"
18289 }
18290 run_test 218 "parallel read and truncate should not deadlock"
18291
18292 test_219() {
18293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18294
18295         # write one partial page
18296         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18297         # set no grant so vvp_io_commit_write will do sync write
18298         $LCTL set_param fail_loc=0x411
18299         # write a full page at the end of file
18300         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18301
18302         $LCTL set_param fail_loc=0
18303         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18304         $LCTL set_param fail_loc=0x411
18305         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18306
18307         # LU-4201
18308         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18309         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18310 }
18311 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18312
18313 test_220() { #LU-325
18314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18315         remote_ost_nodsh && skip "remote OST with nodsh"
18316         remote_mds_nodsh && skip "remote MDS with nodsh"
18317         remote_mgs_nodsh && skip "remote MGS with nodsh"
18318
18319         local OSTIDX=0
18320
18321         # create on MDT0000 so the last_id and next_id are correct
18322         mkdir_on_mdt0 $DIR/$tdir
18323         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18324         OST=${OST%_UUID}
18325
18326         # on the mdt's osc
18327         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18328         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18329                         osp.$mdtosc_proc1.prealloc_last_id)
18330         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18331                         osp.$mdtosc_proc1.prealloc_next_id)
18332
18333         $LFS df -i
18334
18335         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18336         #define OBD_FAIL_OST_ENOINO              0x229
18337         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18338         create_pool $FSNAME.$TESTNAME || return 1
18339         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18340
18341         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18342
18343         MDSOBJS=$((last_id - next_id))
18344         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18345
18346         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18347         echo "OST still has $count kbytes free"
18348
18349         echo "create $MDSOBJS files @next_id..."
18350         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18351
18352         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18353                         osp.$mdtosc_proc1.prealloc_last_id)
18354         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18355                         osp.$mdtosc_proc1.prealloc_next_id)
18356
18357         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18358         $LFS df -i
18359
18360         echo "cleanup..."
18361
18362         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18363         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18364
18365         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18366                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18367         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18368                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18369         echo "unlink $MDSOBJS files @$next_id..."
18370         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18371 }
18372 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18373
18374 test_221() {
18375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18376
18377         dd if=`which date` of=$MOUNT/date oflag=sync
18378         chmod +x $MOUNT/date
18379
18380         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18381         $LCTL set_param fail_loc=0x80001401
18382
18383         $MOUNT/date > /dev/null
18384         rm -f $MOUNT/date
18385 }
18386 run_test 221 "make sure fault and truncate race to not cause OOM"
18387
18388 test_222a () {
18389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18390
18391         rm -rf $DIR/$tdir
18392         test_mkdir $DIR/$tdir
18393         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18394         createmany -o $DIR/$tdir/$tfile 10
18395         cancel_lru_locks mdc
18396         cancel_lru_locks osc
18397         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18398         $LCTL set_param fail_loc=0x31a
18399         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18400         $LCTL set_param fail_loc=0
18401         rm -r $DIR/$tdir
18402 }
18403 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18404
18405 test_222b () {
18406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18407
18408         rm -rf $DIR/$tdir
18409         test_mkdir $DIR/$tdir
18410         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18411         createmany -o $DIR/$tdir/$tfile 10
18412         cancel_lru_locks mdc
18413         cancel_lru_locks osc
18414         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18415         $LCTL set_param fail_loc=0x31a
18416         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18417         $LCTL set_param fail_loc=0
18418 }
18419 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18420
18421 test_223 () {
18422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18423
18424         rm -rf $DIR/$tdir
18425         test_mkdir $DIR/$tdir
18426         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18427         createmany -o $DIR/$tdir/$tfile 10
18428         cancel_lru_locks mdc
18429         cancel_lru_locks osc
18430         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18431         $LCTL set_param fail_loc=0x31b
18432         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18433         $LCTL set_param fail_loc=0
18434         rm -r $DIR/$tdir
18435 }
18436 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18437
18438 test_224a() { # LU-1039, MRP-303
18439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18440
18441         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18442         $LCTL set_param fail_loc=0x508
18443         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18444         $LCTL set_param fail_loc=0
18445         df $DIR
18446 }
18447 run_test 224a "Don't panic on bulk IO failure"
18448
18449 test_224b() { # LU-1039, MRP-303
18450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18451
18452         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18453         cancel_lru_locks osc
18454         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18455         $LCTL set_param fail_loc=0x515
18456         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18457         $LCTL set_param fail_loc=0
18458         df $DIR
18459 }
18460 run_test 224b "Don't panic on bulk IO failure"
18461
18462 test_224c() { # LU-6441
18463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18464         remote_mds_nodsh && skip "remote MDS with nodsh"
18465
18466         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18467         save_writethrough $p
18468         set_cache writethrough on
18469
18470         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18471         local at_max=$($LCTL get_param -n at_max)
18472         local timeout=$($LCTL get_param -n timeout)
18473         local test_at="at_max"
18474         local param_at="$FSNAME.sys.at_max"
18475         local test_timeout="timeout"
18476         local param_timeout="$FSNAME.sys.timeout"
18477
18478         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18479
18480         set_persistent_param_and_check client "$test_at" "$param_at" 0
18481         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18482
18483         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18484         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18485         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18486         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18487         sync
18488         do_facet ost1 "$LCTL set_param fail_loc=0"
18489
18490         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18491         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18492                 $timeout
18493
18494         $LCTL set_param -n $pages_per_rpc
18495         restore_lustre_params < $p
18496         rm -f $p
18497 }
18498 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18499
18500 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18501 test_225a () {
18502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18503         if [ -z ${MDSSURVEY} ]; then
18504                 skip_env "mds-survey not found"
18505         fi
18506         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18507                 skip "Need MDS version at least 2.2.51"
18508
18509         local mds=$(facet_host $SINGLEMDS)
18510         local target=$(do_nodes $mds 'lctl dl' |
18511                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18512
18513         local cmd1="file_count=1000 thrhi=4"
18514         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18515         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18516         local cmd="$cmd1 $cmd2 $cmd3"
18517
18518         rm -f ${TMP}/mds_survey*
18519         echo + $cmd
18520         eval $cmd || error "mds-survey with zero-stripe failed"
18521         cat ${TMP}/mds_survey*
18522         rm -f ${TMP}/mds_survey*
18523 }
18524 run_test 225a "Metadata survey sanity with zero-stripe"
18525
18526 test_225b () {
18527         if [ -z ${MDSSURVEY} ]; then
18528                 skip_env "mds-survey not found"
18529         fi
18530         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18531                 skip "Need MDS version at least 2.2.51"
18532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18533         remote_mds_nodsh && skip "remote MDS with nodsh"
18534         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18535                 skip_env "Need to mount OST to test"
18536         fi
18537
18538         local mds=$(facet_host $SINGLEMDS)
18539         local target=$(do_nodes $mds 'lctl dl' |
18540                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18541
18542         local cmd1="file_count=1000 thrhi=4"
18543         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18544         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18545         local cmd="$cmd1 $cmd2 $cmd3"
18546
18547         rm -f ${TMP}/mds_survey*
18548         echo + $cmd
18549         eval $cmd || error "mds-survey with stripe_count failed"
18550         cat ${TMP}/mds_survey*
18551         rm -f ${TMP}/mds_survey*
18552 }
18553 run_test 225b "Metadata survey sanity with stripe_count = 1"
18554
18555 mcreate_path2fid () {
18556         local mode=$1
18557         local major=$2
18558         local minor=$3
18559         local name=$4
18560         local desc=$5
18561         local path=$DIR/$tdir/$name
18562         local fid
18563         local rc
18564         local fid_path
18565
18566         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18567                 error "cannot create $desc"
18568
18569         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18570         rc=$?
18571         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18572
18573         fid_path=$($LFS fid2path $MOUNT $fid)
18574         rc=$?
18575         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18576
18577         [ "$path" == "$fid_path" ] ||
18578                 error "fid2path returned $fid_path, expected $path"
18579
18580         echo "pass with $path and $fid"
18581 }
18582
18583 test_226a () {
18584         rm -rf $DIR/$tdir
18585         mkdir -p $DIR/$tdir
18586
18587         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18588         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18589         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18590         mcreate_path2fid 0040666 0 0 dir "directory"
18591         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18592         mcreate_path2fid 0100666 0 0 file "regular file"
18593         mcreate_path2fid 0120666 0 0 link "symbolic link"
18594         mcreate_path2fid 0140666 0 0 sock "socket"
18595 }
18596 run_test 226a "call path2fid and fid2path on files of all type"
18597
18598 test_226b () {
18599         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18600
18601         local MDTIDX=1
18602
18603         rm -rf $DIR/$tdir
18604         mkdir -p $DIR/$tdir
18605         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18606                 error "create remote directory failed"
18607         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18608         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18609                                 "character special file (null)"
18610         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18611                                 "character special file (no device)"
18612         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18613         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18614                                 "block special file (loop)"
18615         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18616         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18617         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18618 }
18619 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18620
18621 test_226c () {
18622         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18623         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18624                 skip "Need MDS version at least 2.13.55"
18625
18626         local submnt=/mnt/submnt
18627         local srcfile=/etc/passwd
18628         local dstfile=$submnt/passwd
18629         local path
18630         local fid
18631
18632         rm -rf $DIR/$tdir
18633         rm -rf $submnt
18634         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18635                 error "create remote directory failed"
18636         mkdir -p $submnt || error "create $submnt failed"
18637         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18638                 error "mount $submnt failed"
18639         stack_trap "umount $submnt" EXIT
18640
18641         cp $srcfile $dstfile
18642         fid=$($LFS path2fid $dstfile)
18643         path=$($LFS fid2path $submnt "$fid")
18644         [ "$path" = "$dstfile" ] ||
18645                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18646 }
18647 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18648
18649 # LU-1299 Executing or running ldd on a truncated executable does not
18650 # cause an out-of-memory condition.
18651 test_227() {
18652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18653         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18654
18655         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18656         chmod +x $MOUNT/date
18657
18658         $MOUNT/date > /dev/null
18659         ldd $MOUNT/date > /dev/null
18660         rm -f $MOUNT/date
18661 }
18662 run_test 227 "running truncated executable does not cause OOM"
18663
18664 # LU-1512 try to reuse idle OI blocks
18665 test_228a() {
18666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18667         remote_mds_nodsh && skip "remote MDS with nodsh"
18668         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18669
18670         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18671         local myDIR=$DIR/$tdir
18672
18673         mkdir -p $myDIR
18674         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18675         $LCTL set_param fail_loc=0x80001002
18676         createmany -o $myDIR/t- 10000
18677         $LCTL set_param fail_loc=0
18678         # The guard is current the largest FID holder
18679         touch $myDIR/guard
18680         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18681                     tr -d '[')
18682         local IDX=$(($SEQ % 64))
18683
18684         do_facet $SINGLEMDS sync
18685         # Make sure journal flushed.
18686         sleep 6
18687         local blk1=$(do_facet $SINGLEMDS \
18688                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18689                      grep Blockcount | awk '{print $4}')
18690
18691         # Remove old files, some OI blocks will become idle.
18692         unlinkmany $myDIR/t- 10000
18693         # Create new files, idle OI blocks should be reused.
18694         createmany -o $myDIR/t- 2000
18695         do_facet $SINGLEMDS sync
18696         # Make sure journal flushed.
18697         sleep 6
18698         local blk2=$(do_facet $SINGLEMDS \
18699                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18700                      grep Blockcount | awk '{print $4}')
18701
18702         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18703 }
18704 run_test 228a "try to reuse idle OI blocks"
18705
18706 test_228b() {
18707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18708         remote_mds_nodsh && skip "remote MDS with nodsh"
18709         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18710
18711         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18712         local myDIR=$DIR/$tdir
18713
18714         mkdir -p $myDIR
18715         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18716         $LCTL set_param fail_loc=0x80001002
18717         createmany -o $myDIR/t- 10000
18718         $LCTL set_param fail_loc=0
18719         # The guard is current the largest FID holder
18720         touch $myDIR/guard
18721         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18722                     tr -d '[')
18723         local IDX=$(($SEQ % 64))
18724
18725         do_facet $SINGLEMDS sync
18726         # Make sure journal flushed.
18727         sleep 6
18728         local blk1=$(do_facet $SINGLEMDS \
18729                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18730                      grep Blockcount | awk '{print $4}')
18731
18732         # Remove old files, some OI blocks will become idle.
18733         unlinkmany $myDIR/t- 10000
18734
18735         # stop the MDT
18736         stop $SINGLEMDS || error "Fail to stop MDT."
18737         # remount the MDT
18738         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18739
18740         df $MOUNT || error "Fail to df."
18741         # Create new files, idle OI blocks should be reused.
18742         createmany -o $myDIR/t- 2000
18743         do_facet $SINGLEMDS sync
18744         # Make sure journal flushed.
18745         sleep 6
18746         local blk2=$(do_facet $SINGLEMDS \
18747                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18748                      grep Blockcount | awk '{print $4}')
18749
18750         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18751 }
18752 run_test 228b "idle OI blocks can be reused after MDT restart"
18753
18754 #LU-1881
18755 test_228c() {
18756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18757         remote_mds_nodsh && skip "remote MDS with nodsh"
18758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18759
18760         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18761         local myDIR=$DIR/$tdir
18762
18763         mkdir -p $myDIR
18764         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18765         $LCTL set_param fail_loc=0x80001002
18766         # 20000 files can guarantee there are index nodes in the OI file
18767         createmany -o $myDIR/t- 20000
18768         $LCTL set_param fail_loc=0
18769         # The guard is current the largest FID holder
18770         touch $myDIR/guard
18771         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18772                     tr -d '[')
18773         local IDX=$(($SEQ % 64))
18774
18775         do_facet $SINGLEMDS sync
18776         # Make sure journal flushed.
18777         sleep 6
18778         local blk1=$(do_facet $SINGLEMDS \
18779                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18780                      grep Blockcount | awk '{print $4}')
18781
18782         # Remove old files, some OI blocks will become idle.
18783         unlinkmany $myDIR/t- 20000
18784         rm -f $myDIR/guard
18785         # The OI file should become empty now
18786
18787         # Create new files, idle OI blocks should be reused.
18788         createmany -o $myDIR/t- 2000
18789         do_facet $SINGLEMDS sync
18790         # Make sure journal flushed.
18791         sleep 6
18792         local blk2=$(do_facet $SINGLEMDS \
18793                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18794                      grep Blockcount | awk '{print $4}')
18795
18796         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18797 }
18798 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18799
18800 test_229() { # LU-2482, LU-3448
18801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18802         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18803         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18804                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18805
18806         rm -f $DIR/$tfile
18807
18808         # Create a file with a released layout and stripe count 2.
18809         $MULTIOP $DIR/$tfile H2c ||
18810                 error "failed to create file with released layout"
18811
18812         $LFS getstripe -v $DIR/$tfile
18813
18814         local pattern=$($LFS getstripe -L $DIR/$tfile)
18815         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18816
18817         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18818                 error "getstripe"
18819         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18820         stat $DIR/$tfile || error "failed to stat released file"
18821
18822         chown $RUNAS_ID $DIR/$tfile ||
18823                 error "chown $RUNAS_ID $DIR/$tfile failed"
18824
18825         chgrp $RUNAS_ID $DIR/$tfile ||
18826                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18827
18828         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18829         rm $DIR/$tfile || error "failed to remove released file"
18830 }
18831 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18832
18833 test_230a() {
18834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18835         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18836         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18837                 skip "Need MDS version at least 2.11.52"
18838
18839         local MDTIDX=1
18840
18841         test_mkdir $DIR/$tdir
18842         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18843         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18844         [ $mdt_idx -ne 0 ] &&
18845                 error "create local directory on wrong MDT $mdt_idx"
18846
18847         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18848                         error "create remote directory failed"
18849         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18850         [ $mdt_idx -ne $MDTIDX ] &&
18851                 error "create remote directory on wrong MDT $mdt_idx"
18852
18853         createmany -o $DIR/$tdir/test_230/t- 10 ||
18854                 error "create files on remote directory failed"
18855         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18856         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18857         rm -r $DIR/$tdir || error "unlink remote directory failed"
18858 }
18859 run_test 230a "Create remote directory and files under the remote directory"
18860
18861 test_230b() {
18862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18863         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18864         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18865                 skip "Need MDS version at least 2.11.52"
18866
18867         local MDTIDX=1
18868         local mdt_index
18869         local i
18870         local file
18871         local pid
18872         local stripe_count
18873         local migrate_dir=$DIR/$tdir/migrate_dir
18874         local other_dir=$DIR/$tdir/other_dir
18875
18876         test_mkdir $DIR/$tdir
18877         test_mkdir -i0 -c1 $migrate_dir
18878         test_mkdir -i0 -c1 $other_dir
18879         for ((i=0; i<10; i++)); do
18880                 mkdir -p $migrate_dir/dir_${i}
18881                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18882                         error "create files under remote dir failed $i"
18883         done
18884
18885         cp /etc/passwd $migrate_dir/$tfile
18886         cp /etc/passwd $other_dir/$tfile
18887         chattr +SAD $migrate_dir
18888         chattr +SAD $migrate_dir/$tfile
18889
18890         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18891         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18892         local old_dir_mode=$(stat -c%f $migrate_dir)
18893         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18894
18895         mkdir -p $migrate_dir/dir_default_stripe2
18896         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18897         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18898
18899         mkdir -p $other_dir
18900         ln $migrate_dir/$tfile $other_dir/luna
18901         ln $migrate_dir/$tfile $migrate_dir/sofia
18902         ln $other_dir/$tfile $migrate_dir/david
18903         ln -s $migrate_dir/$tfile $other_dir/zachary
18904         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18905         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18906
18907         local len
18908         local lnktgt
18909
18910         # inline symlink
18911         for len in 58 59 60; do
18912                 lnktgt=$(str_repeat 'l' $len)
18913                 touch $migrate_dir/$lnktgt
18914                 ln -s $lnktgt $migrate_dir/${len}char_ln
18915         done
18916
18917         # PATH_MAX
18918         for len in 4094 4095; do
18919                 lnktgt=$(str_repeat 'l' $len)
18920                 ln -s $lnktgt $migrate_dir/${len}char_ln
18921         done
18922
18923         # NAME_MAX
18924         for len in 254 255; do
18925                 touch $migrate_dir/$(str_repeat 'l' $len)
18926         done
18927
18928         $LFS migrate -m $MDTIDX $migrate_dir ||
18929                 error "fails on migrating remote dir to MDT1"
18930
18931         echo "migratate to MDT1, then checking.."
18932         for ((i = 0; i < 10; i++)); do
18933                 for file in $(find $migrate_dir/dir_${i}); do
18934                         mdt_index=$($LFS getstripe -m $file)
18935                         # broken symlink getstripe will fail
18936                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18937                                 error "$file is not on MDT${MDTIDX}"
18938                 done
18939         done
18940
18941         # the multiple link file should still in MDT0
18942         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18943         [ $mdt_index == 0 ] ||
18944                 error "$file is not on MDT${MDTIDX}"
18945
18946         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18947         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18948                 error " expect $old_dir_flag get $new_dir_flag"
18949
18950         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18951         [ "$old_file_flag" = "$new_file_flag" ] ||
18952                 error " expect $old_file_flag get $new_file_flag"
18953
18954         local new_dir_mode=$(stat -c%f $migrate_dir)
18955         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18956                 error "expect mode $old_dir_mode get $new_dir_mode"
18957
18958         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18959         [ "$old_file_mode" = "$new_file_mode" ] ||
18960                 error "expect mode $old_file_mode get $new_file_mode"
18961
18962         diff /etc/passwd $migrate_dir/$tfile ||
18963                 error "$tfile different after migration"
18964
18965         diff /etc/passwd $other_dir/luna ||
18966                 error "luna different after migration"
18967
18968         diff /etc/passwd $migrate_dir/sofia ||
18969                 error "sofia different after migration"
18970
18971         diff /etc/passwd $migrate_dir/david ||
18972                 error "david different after migration"
18973
18974         diff /etc/passwd $other_dir/zachary ||
18975                 error "zachary different after migration"
18976
18977         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18978                 error "${tfile}_ln different after migration"
18979
18980         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18981                 error "${tfile}_ln_other different after migration"
18982
18983         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18984         [ $stripe_count = 2 ] ||
18985                 error "dir strpe_count $d != 2 after migration."
18986
18987         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18988         [ $stripe_count = 2 ] ||
18989                 error "file strpe_count $d != 2 after migration."
18990
18991         #migrate back to MDT0
18992         MDTIDX=0
18993
18994         $LFS migrate -m $MDTIDX $migrate_dir ||
18995                 error "fails on migrating remote dir to MDT0"
18996
18997         echo "migrate back to MDT0, checking.."
18998         for file in $(find $migrate_dir); do
18999                 mdt_index=$($LFS getstripe -m $file)
19000                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19001                         error "$file is not on MDT${MDTIDX}"
19002         done
19003
19004         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19005         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19006                 error " expect $old_dir_flag get $new_dir_flag"
19007
19008         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19009         [ "$old_file_flag" = "$new_file_flag" ] ||
19010                 error " expect $old_file_flag get $new_file_flag"
19011
19012         local new_dir_mode=$(stat -c%f $migrate_dir)
19013         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19014                 error "expect mode $old_dir_mode get $new_dir_mode"
19015
19016         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19017         [ "$old_file_mode" = "$new_file_mode" ] ||
19018                 error "expect mode $old_file_mode get $new_file_mode"
19019
19020         diff /etc/passwd ${migrate_dir}/$tfile ||
19021                 error "$tfile different after migration"
19022
19023         diff /etc/passwd ${other_dir}/luna ||
19024                 error "luna different after migration"
19025
19026         diff /etc/passwd ${migrate_dir}/sofia ||
19027                 error "sofia different after migration"
19028
19029         diff /etc/passwd ${other_dir}/zachary ||
19030                 error "zachary different after migration"
19031
19032         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19033                 error "${tfile}_ln different after migration"
19034
19035         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19036                 error "${tfile}_ln_other different after migration"
19037
19038         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19039         [ $stripe_count = 2 ] ||
19040                 error "dir strpe_count $d != 2 after migration."
19041
19042         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19043         [ $stripe_count = 2 ] ||
19044                 error "file strpe_count $d != 2 after migration."
19045
19046         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19047 }
19048 run_test 230b "migrate directory"
19049
19050 test_230c() {
19051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19052         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19053         remote_mds_nodsh && skip "remote MDS with nodsh"
19054         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19055                 skip "Need MDS version at least 2.11.52"
19056
19057         local MDTIDX=1
19058         local total=3
19059         local mdt_index
19060         local file
19061         local migrate_dir=$DIR/$tdir/migrate_dir
19062
19063         #If migrating directory fails in the middle, all entries of
19064         #the directory is still accessiable.
19065         test_mkdir $DIR/$tdir
19066         test_mkdir -i0 -c1 $migrate_dir
19067         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19068         stat $migrate_dir
19069         createmany -o $migrate_dir/f $total ||
19070                 error "create files under ${migrate_dir} failed"
19071
19072         # fail after migrating top dir, and this will fail only once, so the
19073         # first sub file migration will fail (currently f3), others succeed.
19074         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19075         do_facet mds1 lctl set_param fail_loc=0x1801
19076         local t=$(ls $migrate_dir | wc -l)
19077         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19078                 error "migrate should fail"
19079         local u=$(ls $migrate_dir | wc -l)
19080         [ "$u" == "$t" ] || error "$u != $t during migration"
19081
19082         # add new dir/file should succeed
19083         mkdir $migrate_dir/dir ||
19084                 error "mkdir failed under migrating directory"
19085         touch $migrate_dir/file ||
19086                 error "create file failed under migrating directory"
19087
19088         # add file with existing name should fail
19089         for file in $migrate_dir/f*; do
19090                 stat $file > /dev/null || error "stat $file failed"
19091                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19092                         error "open(O_CREAT|O_EXCL) $file should fail"
19093                 $MULTIOP $file m && error "create $file should fail"
19094                 touch $DIR/$tdir/remote_dir/$tfile ||
19095                         error "touch $tfile failed"
19096                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19097                         error "link $file should fail"
19098                 mdt_index=$($LFS getstripe -m $file)
19099                 if [ $mdt_index == 0 ]; then
19100                         # file failed to migrate is not allowed to rename to
19101                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19102                                 error "rename to $file should fail"
19103                 else
19104                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19105                                 error "rename to $file failed"
19106                 fi
19107                 echo hello >> $file || error "write $file failed"
19108         done
19109
19110         # resume migration with different options should fail
19111         $LFS migrate -m 0 $migrate_dir &&
19112                 error "migrate -m 0 $migrate_dir should fail"
19113
19114         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19115                 error "migrate -c 2 $migrate_dir should fail"
19116
19117         # resume migration should succeed
19118         $LFS migrate -m $MDTIDX $migrate_dir ||
19119                 error "migrate $migrate_dir failed"
19120
19121         echo "Finish migration, then checking.."
19122         for file in $(find $migrate_dir); do
19123                 mdt_index=$($LFS getstripe -m $file)
19124                 [ $mdt_index == $MDTIDX ] ||
19125                         error "$file is not on MDT${MDTIDX}"
19126         done
19127
19128         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19129 }
19130 run_test 230c "check directory accessiblity if migration failed"
19131
19132 test_230d() {
19133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19134         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19135         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19136                 skip "Need MDS version at least 2.11.52"
19137         # LU-11235
19138         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19139
19140         local migrate_dir=$DIR/$tdir/migrate_dir
19141         local old_index
19142         local new_index
19143         local old_count
19144         local new_count
19145         local new_hash
19146         local mdt_index
19147         local i
19148         local j
19149
19150         old_index=$((RANDOM % MDSCOUNT))
19151         old_count=$((MDSCOUNT - old_index))
19152         new_index=$((RANDOM % MDSCOUNT))
19153         new_count=$((MDSCOUNT - new_index))
19154         new_hash=1 # for all_char
19155
19156         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19157         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19158
19159         test_mkdir $DIR/$tdir
19160         test_mkdir -i $old_index -c $old_count $migrate_dir
19161
19162         for ((i=0; i<100; i++)); do
19163                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19164                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19165                         error "create files under remote dir failed $i"
19166         done
19167
19168         echo -n "Migrate from MDT$old_index "
19169         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19170         echo -n "to MDT$new_index"
19171         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19172         echo
19173
19174         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19175         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19176                 error "migrate remote dir error"
19177
19178         echo "Finish migration, then checking.."
19179         for file in $(find $migrate_dir); do
19180                 mdt_index=$($LFS getstripe -m $file)
19181                 if [ $mdt_index -lt $new_index ] ||
19182                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19183                         error "$file is on MDT$mdt_index"
19184                 fi
19185         done
19186
19187         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19188 }
19189 run_test 230d "check migrate big directory"
19190
19191 test_230e() {
19192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19193         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19194         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19195                 skip "Need MDS version at least 2.11.52"
19196
19197         local i
19198         local j
19199         local a_fid
19200         local b_fid
19201
19202         mkdir_on_mdt0 $DIR/$tdir
19203         mkdir $DIR/$tdir/migrate_dir
19204         mkdir $DIR/$tdir/other_dir
19205         touch $DIR/$tdir/migrate_dir/a
19206         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19207         ls $DIR/$tdir/other_dir
19208
19209         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19210                 error "migrate dir fails"
19211
19212         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19213         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19214
19215         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19216         [ $mdt_index == 0 ] || error "a is not on MDT0"
19217
19218         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19219                 error "migrate dir fails"
19220
19221         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19222         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19223
19224         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19225         [ $mdt_index == 1 ] || error "a is not on MDT1"
19226
19227         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19228         [ $mdt_index == 1 ] || error "b is not on MDT1"
19229
19230         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19231         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19232
19233         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19234
19235         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19236 }
19237 run_test 230e "migrate mulitple local link files"
19238
19239 test_230f() {
19240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19242         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19243                 skip "Need MDS version at least 2.11.52"
19244
19245         local a_fid
19246         local ln_fid
19247
19248         mkdir -p $DIR/$tdir
19249         mkdir $DIR/$tdir/migrate_dir
19250         $LFS mkdir -i1 $DIR/$tdir/other_dir
19251         touch $DIR/$tdir/migrate_dir/a
19252         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19253         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19254         ls $DIR/$tdir/other_dir
19255
19256         # a should be migrated to MDT1, since no other links on MDT0
19257         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19258                 error "#1 migrate dir fails"
19259         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19260         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19261         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19262         [ $mdt_index == 1 ] || error "a is not on MDT1"
19263
19264         # a should stay on MDT1, because it is a mulitple link file
19265         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19266                 error "#2 migrate dir fails"
19267         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19268         [ $mdt_index == 1 ] || error "a is not on MDT1"
19269
19270         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19271                 error "#3 migrate dir fails"
19272
19273         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19274         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19275         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19276
19277         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19278         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19279
19280         # a should be migrated to MDT0, since no other links on MDT1
19281         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19282                 error "#4 migrate dir fails"
19283         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19284         [ $mdt_index == 0 ] || error "a is not on MDT0"
19285
19286         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19287 }
19288 run_test 230f "migrate mulitple remote link files"
19289
19290 test_230g() {
19291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19292         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19293         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19294                 skip "Need MDS version at least 2.11.52"
19295
19296         mkdir -p $DIR/$tdir/migrate_dir
19297
19298         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19299                 error "migrating dir to non-exist MDT succeeds"
19300         true
19301 }
19302 run_test 230g "migrate dir to non-exist MDT"
19303
19304 test_230h() {
19305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19306         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19307         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19308                 skip "Need MDS version at least 2.11.52"
19309
19310         local mdt_index
19311
19312         mkdir -p $DIR/$tdir/migrate_dir
19313
19314         $LFS migrate -m1 $DIR &&
19315                 error "migrating mountpoint1 should fail"
19316
19317         $LFS migrate -m1 $DIR/$tdir/.. &&
19318                 error "migrating mountpoint2 should fail"
19319
19320         # same as mv
19321         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19322                 error "migrating $tdir/migrate_dir/.. should fail"
19323
19324         true
19325 }
19326 run_test 230h "migrate .. and root"
19327
19328 test_230i() {
19329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19330         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19331         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19332                 skip "Need MDS version at least 2.11.52"
19333
19334         mkdir -p $DIR/$tdir/migrate_dir
19335
19336         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19337                 error "migration fails with a tailing slash"
19338
19339         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19340                 error "migration fails with two tailing slashes"
19341 }
19342 run_test 230i "lfs migrate -m tolerates trailing slashes"
19343
19344 test_230j() {
19345         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19346         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19347                 skip "Need MDS version at least 2.11.52"
19348
19349         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19350         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19351                 error "create $tfile failed"
19352         cat /etc/passwd > $DIR/$tdir/$tfile
19353
19354         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19355
19356         cmp /etc/passwd $DIR/$tdir/$tfile ||
19357                 error "DoM file mismatch after migration"
19358 }
19359 run_test 230j "DoM file data not changed after dir migration"
19360
19361 test_230k() {
19362         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19363         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19364                 skip "Need MDS version at least 2.11.56"
19365
19366         local total=20
19367         local files_on_starting_mdt=0
19368
19369         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19370         $LFS getdirstripe $DIR/$tdir
19371         for i in $(seq $total); do
19372                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19373                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19374                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19375         done
19376
19377         echo "$files_on_starting_mdt files on MDT0"
19378
19379         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19380         $LFS getdirstripe $DIR/$tdir
19381
19382         files_on_starting_mdt=0
19383         for i in $(seq $total); do
19384                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19385                         error "file $tfile.$i mismatch after migration"
19386                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19387                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19388         done
19389
19390         echo "$files_on_starting_mdt files on MDT1 after migration"
19391         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19392
19393         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19394         $LFS getdirstripe $DIR/$tdir
19395
19396         files_on_starting_mdt=0
19397         for i in $(seq $total); do
19398                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19399                         error "file $tfile.$i mismatch after 2nd migration"
19400                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19401                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19402         done
19403
19404         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19405         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19406
19407         true
19408 }
19409 run_test 230k "file data not changed after dir migration"
19410
19411 test_230l() {
19412         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19413         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19414                 skip "Need MDS version at least 2.11.56"
19415
19416         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19417         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19418                 error "create files under remote dir failed $i"
19419         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19420 }
19421 run_test 230l "readdir between MDTs won't crash"
19422
19423 test_230m() {
19424         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19425         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19426                 skip "Need MDS version at least 2.11.56"
19427
19428         local MDTIDX=1
19429         local mig_dir=$DIR/$tdir/migrate_dir
19430         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19431         local shortstr="b"
19432         local val
19433
19434         echo "Creating files and dirs with xattrs"
19435         test_mkdir $DIR/$tdir
19436         test_mkdir -i0 -c1 $mig_dir
19437         mkdir $mig_dir/dir
19438         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19439                 error "cannot set xattr attr1 on dir"
19440         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19441                 error "cannot set xattr attr2 on dir"
19442         touch $mig_dir/dir/f0
19443         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19444                 error "cannot set xattr attr1 on file"
19445         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19446                 error "cannot set xattr attr2 on file"
19447         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19448         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19449         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19450         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19451         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19452         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19453         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19454         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19455         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19456
19457         echo "Migrating to MDT1"
19458         $LFS migrate -m $MDTIDX $mig_dir ||
19459                 error "fails on migrating dir to MDT1"
19460
19461         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19462         echo "Checking xattrs"
19463         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19464         [ "$val" = $longstr ] ||
19465                 error "expecting xattr1 $longstr on dir, found $val"
19466         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19467         [ "$val" = $shortstr ] ||
19468                 error "expecting xattr2 $shortstr on dir, found $val"
19469         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19470         [ "$val" = $longstr ] ||
19471                 error "expecting xattr1 $longstr on file, found $val"
19472         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19473         [ "$val" = $shortstr ] ||
19474                 error "expecting xattr2 $shortstr on file, found $val"
19475 }
19476 run_test 230m "xattrs not changed after dir migration"
19477
19478 test_230n() {
19479         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19480         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19481                 skip "Need MDS version at least 2.13.53"
19482
19483         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19484         cat /etc/hosts > $DIR/$tdir/$tfile
19485         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19486         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19487
19488         cmp /etc/hosts $DIR/$tdir/$tfile ||
19489                 error "File data mismatch after migration"
19490 }
19491 run_test 230n "Dir migration with mirrored file"
19492
19493 test_230o() {
19494         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19495         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19496                 skip "Need MDS version at least 2.13.52"
19497
19498         local mdts=$(comma_list $(mdts_nodes))
19499         local timeout=100
19500         local restripe_status
19501         local delta
19502         local i
19503
19504         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19505
19506         # in case "crush" hash type is not set
19507         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19508
19509         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19510                            mdt.*MDT0000.enable_dir_restripe)
19511         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19512         stack_trap "do_nodes $mdts $LCTL set_param \
19513                     mdt.*.enable_dir_restripe=$restripe_status"
19514
19515         mkdir $DIR/$tdir
19516         createmany -m $DIR/$tdir/f 100 ||
19517                 error "create files under remote dir failed $i"
19518         createmany -d $DIR/$tdir/d 100 ||
19519                 error "create dirs under remote dir failed $i"
19520
19521         for i in $(seq 2 $MDSCOUNT); do
19522                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19523                 $LFS setdirstripe -c $i $DIR/$tdir ||
19524                         error "split -c $i $tdir failed"
19525                 wait_update $HOSTNAME \
19526                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19527                         error "dir split not finished"
19528                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19529                         awk '/migrate/ {sum += $2} END { print sum }')
19530                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19531                 # delta is around total_files/stripe_count
19532                 (( $delta < 200 / (i - 1) + 4 )) ||
19533                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19534         done
19535 }
19536 run_test 230o "dir split"
19537
19538 test_230p() {
19539         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19540         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19541                 skip "Need MDS version at least 2.13.52"
19542
19543         local mdts=$(comma_list $(mdts_nodes))
19544         local timeout=100
19545         local restripe_status
19546         local delta
19547         local i
19548
19549         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19550
19551         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19552
19553         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19554                            mdt.*MDT0000.enable_dir_restripe)
19555         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19556         stack_trap "do_nodes $mdts $LCTL set_param \
19557                     mdt.*.enable_dir_restripe=$restripe_status"
19558
19559         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19560         createmany -m $DIR/$tdir/f 100 ||
19561                 error "create files under remote dir failed $i"
19562         createmany -d $DIR/$tdir/d 100 ||
19563                 error "create dirs under remote dir failed $i"
19564
19565         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19566                 local mdt_hash="crush"
19567
19568                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19569                 $LFS setdirstripe -c $i $DIR/$tdir ||
19570                         error "split -c $i $tdir failed"
19571                 [ $i -eq 1 ] && mdt_hash="none"
19572                 wait_update $HOSTNAME \
19573                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19574                         error "dir merge not finished"
19575                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19576                         awk '/migrate/ {sum += $2} END { print sum }')
19577                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19578                 # delta is around total_files/stripe_count
19579                 (( $delta < 200 / i + 4 )) ||
19580                         error "$delta files migrated >= $((200 / i + 4))"
19581         done
19582 }
19583 run_test 230p "dir merge"
19584
19585 test_230q() {
19586         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19587         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19588                 skip "Need MDS version at least 2.13.52"
19589
19590         local mdts=$(comma_list $(mdts_nodes))
19591         local saved_threshold=$(do_facet mds1 \
19592                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19593         local saved_delta=$(do_facet mds1 \
19594                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19595         local threshold=100
19596         local delta=2
19597         local total=0
19598         local stripe_count=0
19599         local stripe_index
19600         local nr_files
19601         local create
19602
19603         # test with fewer files on ZFS
19604         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19605
19606         stack_trap "do_nodes $mdts $LCTL set_param \
19607                     mdt.*.dir_split_count=$saved_threshold"
19608         stack_trap "do_nodes $mdts $LCTL set_param \
19609                     mdt.*.dir_split_delta=$saved_delta"
19610         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19611         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19612         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19613         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19614         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19615         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19616
19617         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19618         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19619
19620         create=$((threshold * 3 / 2))
19621         while [ $stripe_count -lt $MDSCOUNT ]; do
19622                 createmany -m $DIR/$tdir/f $total $create ||
19623                         error "create sub files failed"
19624                 stat $DIR/$tdir > /dev/null
19625                 total=$((total + create))
19626                 stripe_count=$((stripe_count + delta))
19627                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19628
19629                 wait_update $HOSTNAME \
19630                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19631                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19632
19633                 wait_update $HOSTNAME \
19634                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19635                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19636
19637                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19638                 echo "$nr_files/$total files on MDT$stripe_index after split"
19639                 # allow 10% margin of imbalance with crush hash
19640                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19641                         error "$nr_files files on MDT$stripe_index after split"
19642
19643                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19644                 [ $nr_files -eq $total ] ||
19645                         error "total sub files $nr_files != $total"
19646         done
19647 }
19648 run_test 230q "dir auto split"
19649
19650 test_230r() {
19651         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19652         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19653         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19654                 skip "Need MDS version at least 2.13.54"
19655
19656         # maximum amount of local locks:
19657         # parent striped dir - 2 locks
19658         # new stripe in parent to migrate to - 1 lock
19659         # source and target - 2 locks
19660         # Total 5 locks for regular file
19661         mkdir -p $DIR/$tdir
19662         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19663         touch $DIR/$tdir/dir1/eee
19664
19665         # create 4 hardlink for 4 more locks
19666         # Total: 9 locks > RS_MAX_LOCKS (8)
19667         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19668         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19669         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19670         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19671         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19672         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19673         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19674         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19675
19676         cancel_lru_locks mdc
19677
19678         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19679                 error "migrate dir fails"
19680
19681         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19682 }
19683 run_test 230r "migrate with too many local locks"
19684
19685 test_230s() {
19686         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19687                 skip "Need MDS version at least 2.13.57"
19688
19689         local mdts=$(comma_list $(mdts_nodes))
19690         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19691                                 mdt.*MDT0000.enable_dir_restripe)
19692
19693         stack_trap "do_nodes $mdts $LCTL set_param \
19694                     mdt.*.enable_dir_restripe=$restripe_status"
19695
19696         local st
19697         for st in 0 1; do
19698                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19699                 test_mkdir $DIR/$tdir
19700                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19701                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19702                 rmdir $DIR/$tdir
19703         done
19704 }
19705 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19706
19707 test_230t()
19708 {
19709         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19710         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19711                 skip "Need MDS version at least 2.14.50"
19712
19713         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19714         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19715         $LFS project -p 1 -s $DIR/$tdir ||
19716                 error "set $tdir project id failed"
19717         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19718                 error "set subdir project id failed"
19719         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19720 }
19721 run_test 230t "migrate directory with project ID set"
19722
19723 test_231a()
19724 {
19725         # For simplicity this test assumes that max_pages_per_rpc
19726         # is the same across all OSCs
19727         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19728         local bulk_size=$((max_pages * PAGE_SIZE))
19729         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19730                                        head -n 1)
19731
19732         mkdir -p $DIR/$tdir
19733         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19734                 error "failed to set stripe with -S ${brw_size}M option"
19735
19736         # clear the OSC stats
19737         $LCTL set_param osc.*.stats=0 &>/dev/null
19738         stop_writeback
19739
19740         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19741         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19742                 oflag=direct &>/dev/null || error "dd failed"
19743
19744         sync; sleep 1; sync # just to be safe
19745         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19746         if [ x$nrpcs != "x1" ]; then
19747                 $LCTL get_param osc.*.stats
19748                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19749         fi
19750
19751         start_writeback
19752         # Drop the OSC cache, otherwise we will read from it
19753         cancel_lru_locks osc
19754
19755         # clear the OSC stats
19756         $LCTL set_param osc.*.stats=0 &>/dev/null
19757
19758         # Client reads $bulk_size.
19759         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19760                 iflag=direct &>/dev/null || error "dd failed"
19761
19762         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19763         if [ x$nrpcs != "x1" ]; then
19764                 $LCTL get_param osc.*.stats
19765                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19766         fi
19767 }
19768 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19769
19770 test_231b() {
19771         mkdir -p $DIR/$tdir
19772         local i
19773         for i in {0..1023}; do
19774                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19775                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19776                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19777         done
19778         sync
19779 }
19780 run_test 231b "must not assert on fully utilized OST request buffer"
19781
19782 test_232a() {
19783         mkdir -p $DIR/$tdir
19784         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19785
19786         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19787         do_facet ost1 $LCTL set_param fail_loc=0x31c
19788
19789         # ignore dd failure
19790         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19791
19792         do_facet ost1 $LCTL set_param fail_loc=0
19793         umount_client $MOUNT || error "umount failed"
19794         mount_client $MOUNT || error "mount failed"
19795         stop ost1 || error "cannot stop ost1"
19796         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19797 }
19798 run_test 232a "failed lock should not block umount"
19799
19800 test_232b() {
19801         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19802                 skip "Need MDS version at least 2.10.58"
19803
19804         mkdir -p $DIR/$tdir
19805         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19806         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19807         sync
19808         cancel_lru_locks osc
19809
19810         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19811         do_facet ost1 $LCTL set_param fail_loc=0x31c
19812
19813         # ignore failure
19814         $LFS data_version $DIR/$tdir/$tfile || true
19815
19816         do_facet ost1 $LCTL set_param fail_loc=0
19817         umount_client $MOUNT || error "umount failed"
19818         mount_client $MOUNT || error "mount failed"
19819         stop ost1 || error "cannot stop ost1"
19820         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19821 }
19822 run_test 232b "failed data version lock should not block umount"
19823
19824 test_233a() {
19825         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19826                 skip "Need MDS version at least 2.3.64"
19827         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19828
19829         local fid=$($LFS path2fid $MOUNT)
19830
19831         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19832                 error "cannot access $MOUNT using its FID '$fid'"
19833 }
19834 run_test 233a "checking that OBF of the FS root succeeds"
19835
19836 test_233b() {
19837         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19838                 skip "Need MDS version at least 2.5.90"
19839         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19840
19841         local fid=$($LFS path2fid $MOUNT/.lustre)
19842
19843         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19844                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19845
19846         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19847         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19848                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19849 }
19850 run_test 233b "checking that OBF of the FS .lustre succeeds"
19851
19852 test_234() {
19853         local p="$TMP/sanityN-$TESTNAME.parameters"
19854         save_lustre_params client "llite.*.xattr_cache" > $p
19855         lctl set_param llite.*.xattr_cache 1 ||
19856                 skip_env "xattr cache is not supported"
19857
19858         mkdir -p $DIR/$tdir || error "mkdir failed"
19859         touch $DIR/$tdir/$tfile || error "touch failed"
19860         # OBD_FAIL_LLITE_XATTR_ENOMEM
19861         $LCTL set_param fail_loc=0x1405
19862         getfattr -n user.attr $DIR/$tdir/$tfile &&
19863                 error "getfattr should have failed with ENOMEM"
19864         $LCTL set_param fail_loc=0x0
19865         rm -rf $DIR/$tdir
19866
19867         restore_lustre_params < $p
19868         rm -f $p
19869 }
19870 run_test 234 "xattr cache should not crash on ENOMEM"
19871
19872 test_235() {
19873         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19874                 skip "Need MDS version at least 2.4.52"
19875
19876         flock_deadlock $DIR/$tfile
19877         local RC=$?
19878         case $RC in
19879                 0)
19880                 ;;
19881                 124) error "process hangs on a deadlock"
19882                 ;;
19883                 *) error "error executing flock_deadlock $DIR/$tfile"
19884                 ;;
19885         esac
19886 }
19887 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19888
19889 #LU-2935
19890 test_236() {
19891         check_swap_layouts_support
19892
19893         local ref1=/etc/passwd
19894         local ref2=/etc/group
19895         local file1=$DIR/$tdir/f1
19896         local file2=$DIR/$tdir/f2
19897
19898         test_mkdir -c1 $DIR/$tdir
19899         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19900         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19901         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19902         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19903         local fd=$(free_fd)
19904         local cmd="exec $fd<>$file2"
19905         eval $cmd
19906         rm $file2
19907         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19908                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19909         cmd="exec $fd>&-"
19910         eval $cmd
19911         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19912
19913         #cleanup
19914         rm -rf $DIR/$tdir
19915 }
19916 run_test 236 "Layout swap on open unlinked file"
19917
19918 # LU-4659 linkea consistency
19919 test_238() {
19920         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19921                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19922                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19923                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19924
19925         touch $DIR/$tfile
19926         ln $DIR/$tfile $DIR/$tfile.lnk
19927         touch $DIR/$tfile.new
19928         mv $DIR/$tfile.new $DIR/$tfile
19929         local fid1=$($LFS path2fid $DIR/$tfile)
19930         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19931         local path1=$($LFS fid2path $FSNAME "$fid1")
19932         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19933         local path2=$($LFS fid2path $FSNAME "$fid2")
19934         [ $tfile.lnk == $path2 ] ||
19935                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19936         rm -f $DIR/$tfile*
19937 }
19938 run_test 238 "Verify linkea consistency"
19939
19940 test_239A() { # was test_239
19941         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19942                 skip "Need MDS version at least 2.5.60"
19943
19944         local list=$(comma_list $(mdts_nodes))
19945
19946         mkdir -p $DIR/$tdir
19947         createmany -o $DIR/$tdir/f- 5000
19948         unlinkmany $DIR/$tdir/f- 5000
19949         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19950                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19951         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19952                         osp.*MDT*.sync_in_flight" | calc_sum)
19953         [ "$changes" -eq 0 ] || error "$changes not synced"
19954 }
19955 run_test 239A "osp_sync test"
19956
19957 test_239a() { #LU-5297
19958         remote_mds_nodsh && skip "remote MDS with nodsh"
19959
19960         touch $DIR/$tfile
19961         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19962         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19963         chgrp $RUNAS_GID $DIR/$tfile
19964         wait_delete_completed
19965 }
19966 run_test 239a "process invalid osp sync record correctly"
19967
19968 test_239b() { #LU-5297
19969         remote_mds_nodsh && skip "remote MDS with nodsh"
19970
19971         touch $DIR/$tfile1
19972         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19973         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19974         chgrp $RUNAS_GID $DIR/$tfile1
19975         wait_delete_completed
19976         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19977         touch $DIR/$tfile2
19978         chgrp $RUNAS_GID $DIR/$tfile2
19979         wait_delete_completed
19980 }
19981 run_test 239b "process osp sync record with ENOMEM error correctly"
19982
19983 test_240() {
19984         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19985         remote_mds_nodsh && skip "remote MDS with nodsh"
19986
19987         mkdir -p $DIR/$tdir
19988
19989         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19990                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19991         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19992                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19993
19994         umount_client $MOUNT || error "umount failed"
19995         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19996         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19997         mount_client $MOUNT || error "failed to mount client"
19998
19999         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20000         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20001 }
20002 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20003
20004 test_241_bio() {
20005         local count=$1
20006         local bsize=$2
20007
20008         for LOOP in $(seq $count); do
20009                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20010                 cancel_lru_locks $OSC || true
20011         done
20012 }
20013
20014 test_241_dio() {
20015         local count=$1
20016         local bsize=$2
20017
20018         for LOOP in $(seq $1); do
20019                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20020                         2>/dev/null
20021         done
20022 }
20023
20024 test_241a() { # was test_241
20025         local bsize=$PAGE_SIZE
20026
20027         (( bsize < 40960 )) && bsize=40960
20028         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20029         ls -la $DIR/$tfile
20030         cancel_lru_locks $OSC
20031         test_241_bio 1000 $bsize &
20032         PID=$!
20033         test_241_dio 1000 $bsize
20034         wait $PID
20035 }
20036 run_test 241a "bio vs dio"
20037
20038 test_241b() {
20039         local bsize=$PAGE_SIZE
20040
20041         (( bsize < 40960 )) && bsize=40960
20042         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20043         ls -la $DIR/$tfile
20044         test_241_dio 1000 $bsize &
20045         PID=$!
20046         test_241_dio 1000 $bsize
20047         wait $PID
20048 }
20049 run_test 241b "dio vs dio"
20050
20051 test_242() {
20052         remote_mds_nodsh && skip "remote MDS with nodsh"
20053
20054         mkdir_on_mdt0 $DIR/$tdir
20055         touch $DIR/$tdir/$tfile
20056
20057         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20058         do_facet mds1 lctl set_param fail_loc=0x105
20059         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20060
20061         do_facet mds1 lctl set_param fail_loc=0
20062         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20063 }
20064 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20065
20066 test_243()
20067 {
20068         test_mkdir $DIR/$tdir
20069         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20070 }
20071 run_test 243 "various group lock tests"
20072
20073 test_244a()
20074 {
20075         test_mkdir $DIR/$tdir
20076         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20077         sendfile_grouplock $DIR/$tdir/$tfile || \
20078                 error "sendfile+grouplock failed"
20079         rm -rf $DIR/$tdir
20080 }
20081 run_test 244a "sendfile with group lock tests"
20082
20083 test_244b()
20084 {
20085         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20086
20087         local threads=50
20088         local size=$((1024*1024))
20089
20090         test_mkdir $DIR/$tdir
20091         for i in $(seq 1 $threads); do
20092                 local file=$DIR/$tdir/file_$((i / 10))
20093                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20094                 local pids[$i]=$!
20095         done
20096         for i in $(seq 1 $threads); do
20097                 wait ${pids[$i]}
20098         done
20099 }
20100 run_test 244b "multi-threaded write with group lock"
20101
20102 test_245() {
20103         local flagname="multi_mod_rpcs"
20104         local connect_data_name="max_mod_rpcs"
20105         local out
20106
20107         # check if multiple modify RPCs flag is set
20108         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20109                 grep "connect_flags:")
20110         echo "$out"
20111
20112         echo "$out" | grep -qw $flagname
20113         if [ $? -ne 0 ]; then
20114                 echo "connect flag $flagname is not set"
20115                 return
20116         fi
20117
20118         # check if multiple modify RPCs data is set
20119         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20120         echo "$out"
20121
20122         echo "$out" | grep -qw $connect_data_name ||
20123                 error "import should have connect data $connect_data_name"
20124 }
20125 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20126
20127 cleanup_247() {
20128         local submount=$1
20129
20130         trap 0
20131         umount_client $submount
20132         rmdir $submount
20133 }
20134
20135 test_247a() {
20136         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20137                 grep -q subtree ||
20138                 skip_env "Fileset feature is not supported"
20139
20140         local submount=${MOUNT}_$tdir
20141
20142         mkdir $MOUNT/$tdir
20143         mkdir -p $submount || error "mkdir $submount failed"
20144         FILESET="$FILESET/$tdir" mount_client $submount ||
20145                 error "mount $submount failed"
20146         trap "cleanup_247 $submount" EXIT
20147         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20148         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20149                 error "read $MOUNT/$tdir/$tfile failed"
20150         cleanup_247 $submount
20151 }
20152 run_test 247a "mount subdir as fileset"
20153
20154 test_247b() {
20155         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20156                 skip_env "Fileset feature is not supported"
20157
20158         local submount=${MOUNT}_$tdir
20159
20160         rm -rf $MOUNT/$tdir
20161         mkdir -p $submount || error "mkdir $submount failed"
20162         SKIP_FILESET=1
20163         FILESET="$FILESET/$tdir" mount_client $submount &&
20164                 error "mount $submount should fail"
20165         rmdir $submount
20166 }
20167 run_test 247b "mount subdir that dose not exist"
20168
20169 test_247c() {
20170         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20171                 skip_env "Fileset feature is not supported"
20172
20173         local submount=${MOUNT}_$tdir
20174
20175         mkdir -p $MOUNT/$tdir/dir1
20176         mkdir -p $submount || error "mkdir $submount failed"
20177         trap "cleanup_247 $submount" EXIT
20178         FILESET="$FILESET/$tdir" mount_client $submount ||
20179                 error "mount $submount failed"
20180         local fid=$($LFS path2fid $MOUNT/)
20181         $LFS fid2path $submount $fid && error "fid2path should fail"
20182         cleanup_247 $submount
20183 }
20184 run_test 247c "running fid2path outside subdirectory root"
20185
20186 test_247d() {
20187         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20188                 skip "Fileset feature is not supported"
20189
20190         local submount=${MOUNT}_$tdir
20191
20192         mkdir -p $MOUNT/$tdir/dir1
20193         mkdir -p $submount || error "mkdir $submount failed"
20194         FILESET="$FILESET/$tdir" mount_client $submount ||
20195                 error "mount $submount failed"
20196         trap "cleanup_247 $submount" EXIT
20197
20198         local td=$submount/dir1
20199         local fid=$($LFS path2fid $td)
20200         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20201
20202         # check that we get the same pathname back
20203         local rootpath
20204         local found
20205         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20206                 echo "$rootpath $fid"
20207                 found=$($LFS fid2path $rootpath "$fid")
20208                 [ -n "found" ] || error "fid2path should succeed"
20209                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20210         done
20211         # check wrong root path format
20212         rootpath=$submount"_wrong"
20213         found=$($LFS fid2path $rootpath "$fid")
20214         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20215
20216         cleanup_247 $submount
20217 }
20218 run_test 247d "running fid2path inside subdirectory root"
20219
20220 # LU-8037
20221 test_247e() {
20222         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20223                 grep -q subtree ||
20224                 skip "Fileset feature is not supported"
20225
20226         local submount=${MOUNT}_$tdir
20227
20228         mkdir $MOUNT/$tdir
20229         mkdir -p $submount || error "mkdir $submount failed"
20230         FILESET="$FILESET/.." mount_client $submount &&
20231                 error "mount $submount should fail"
20232         rmdir $submount
20233 }
20234 run_test 247e "mount .. as fileset"
20235
20236 test_247f() {
20237         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20238         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20239                 skip "Need at least version 2.13.52"
20240         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20241                 skip "Need at least version 2.14.50"
20242         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20243                 grep -q subtree ||
20244                 skip "Fileset feature is not supported"
20245
20246         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20247         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20248                 error "mkdir remote failed"
20249         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
20250         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20251                 error "mkdir striped failed"
20252         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20253
20254         local submount=${MOUNT}_$tdir
20255
20256         mkdir -p $submount || error "mkdir $submount failed"
20257         stack_trap "rmdir $submount"
20258
20259         local dir
20260         local stat
20261         local fileset=$FILESET
20262         local mdts=$(comma_list $(mdts_nodes))
20263
20264         stat=$(do_facet mds1 $LCTL get_param -n \
20265                 mdt.*MDT0000.enable_remote_subdir_mount)
20266         stack_trap "do_nodes $mdts $LCTL set_param \
20267                 mdt.*.enable_remote_subdir_mount=$stat"
20268
20269         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20270         stack_trap "umount_client $submount"
20271         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20272                 error "mount remote dir $dir should fail"
20273
20274         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20275                 $tdir/striped/. ; do
20276                 FILESET="$fileset/$dir" mount_client $submount ||
20277                         error "mount $dir failed"
20278                 umount_client $submount
20279         done
20280
20281         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20282         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20283                 error "mount $tdir/remote failed"
20284 }
20285 run_test 247f "mount striped or remote directory as fileset"
20286
20287 test_247g() {
20288         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20289         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20290                 skip "Need at least version 2.14.50"
20291
20292         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20293                 error "mkdir $tdir failed"
20294         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20295
20296         local submount=${MOUNT}_$tdir
20297
20298         mkdir -p $submount || error "mkdir $submount failed"
20299         stack_trap "rmdir $submount"
20300
20301         FILESET="$fileset/$tdir" mount_client $submount ||
20302                 error "mount $dir failed"
20303         stack_trap "umount $submount"
20304
20305         local mdts=$(comma_list $(mdts_nodes))
20306
20307         local nrpcs
20308
20309         stat $submount > /dev/null
20310         cancel_lru_locks $MDC
20311         stat $submount > /dev/null
20312         stat $submount/$tfile > /dev/null
20313         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20314         stat $submount/$tfile > /dev/null
20315         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20316                 awk '/getattr/ {sum += $2} END {print sum}')
20317
20318         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20319 }
20320 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20321
20322 test_248a() {
20323         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20324         [ -z "$fast_read_sav" ] && skip "no fast read support"
20325
20326         # create a large file for fast read verification
20327         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20328
20329         # make sure the file is created correctly
20330         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20331                 { rm -f $DIR/$tfile; skip "file creation error"; }
20332
20333         echo "Test 1: verify that fast read is 4 times faster on cache read"
20334
20335         # small read with fast read enabled
20336         $LCTL set_param -n llite.*.fast_read=1
20337         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20338                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20339                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20340         # small read with fast read disabled
20341         $LCTL set_param -n llite.*.fast_read=0
20342         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20343                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20344                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20345
20346         # verify that fast read is 4 times faster for cache read
20347         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20348                 error_not_in_vm "fast read was not 4 times faster: " \
20349                            "$t_fast vs $t_slow"
20350
20351         echo "Test 2: verify the performance between big and small read"
20352         $LCTL set_param -n llite.*.fast_read=1
20353
20354         # 1k non-cache read
20355         cancel_lru_locks osc
20356         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20357                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20358                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20359
20360         # 1M non-cache read
20361         cancel_lru_locks osc
20362         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20363                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20364                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20365
20366         # verify that big IO is not 4 times faster than small IO
20367         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20368                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20369
20370         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20371         rm -f $DIR/$tfile
20372 }
20373 run_test 248a "fast read verification"
20374
20375 test_248b() {
20376         # Default short_io_bytes=16384, try both smaller and larger sizes.
20377         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20378         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20379         echo "bs=53248 count=113 normal buffered write"
20380         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20381                 error "dd of initial data file failed"
20382         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20383
20384         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20385         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20386                 error "dd with sync normal writes failed"
20387         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20388
20389         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20390         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20391                 error "dd with sync small writes failed"
20392         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20393
20394         cancel_lru_locks osc
20395
20396         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20397         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20398         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20399         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20400                 iflag=direct || error "dd with O_DIRECT small read failed"
20401         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20402         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20403                 error "compare $TMP/$tfile.1 failed"
20404
20405         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20406         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20407
20408         # just to see what the maximum tunable value is, and test parsing
20409         echo "test invalid parameter 2MB"
20410         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20411                 error "too-large short_io_bytes allowed"
20412         echo "test maximum parameter 512KB"
20413         # if we can set a larger short_io_bytes, run test regardless of version
20414         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20415                 # older clients may not allow setting it this large, that's OK
20416                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20417                         skip "Need at least client version 2.13.50"
20418                 error "medium short_io_bytes failed"
20419         fi
20420         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20421         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20422
20423         echo "test large parameter 64KB"
20424         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20425         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20426
20427         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20428         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20429                 error "dd with sync large writes failed"
20430         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20431
20432         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20433         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20434         num=$((113 * 4096 / PAGE_SIZE))
20435         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20436         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20437                 error "dd with O_DIRECT large writes failed"
20438         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20439                 error "compare $DIR/$tfile.3 failed"
20440
20441         cancel_lru_locks osc
20442
20443         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20444         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20445                 error "dd with O_DIRECT large read failed"
20446         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20447                 error "compare $TMP/$tfile.2 failed"
20448
20449         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20450         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20451                 error "dd with O_DIRECT large read failed"
20452         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20453                 error "compare $TMP/$tfile.3 failed"
20454 }
20455 run_test 248b "test short_io read and write for both small and large sizes"
20456
20457 test_249() { # LU-7890
20458         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20459                 skip "Need at least version 2.8.54"
20460
20461         rm -f $DIR/$tfile
20462         $LFS setstripe -c 1 $DIR/$tfile
20463         # Offset 2T == 4k * 512M
20464         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20465                 error "dd to 2T offset failed"
20466 }
20467 run_test 249 "Write above 2T file size"
20468
20469 test_250() {
20470         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20471          && skip "no 16TB file size limit on ZFS"
20472
20473         $LFS setstripe -c 1 $DIR/$tfile
20474         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20475         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20476         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20477         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20478                 conv=notrunc,fsync && error "append succeeded"
20479         return 0
20480 }
20481 run_test 250 "Write above 16T limit"
20482
20483 test_251() {
20484         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20485
20486         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20487         #Skip once - writing the first stripe will succeed
20488         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20489         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20490                 error "short write happened"
20491
20492         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20493         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20494                 error "short read happened"
20495
20496         rm -f $DIR/$tfile
20497 }
20498 run_test 251 "Handling short read and write correctly"
20499
20500 test_252() {
20501         remote_mds_nodsh && skip "remote MDS with nodsh"
20502         remote_ost_nodsh && skip "remote OST with nodsh"
20503         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20504                 skip_env "ldiskfs only test"
20505         fi
20506
20507         local tgt
20508         local dev
20509         local out
20510         local uuid
20511         local num
20512         local gen
20513
20514         # check lr_reader on OST0000
20515         tgt=ost1
20516         dev=$(facet_device $tgt)
20517         out=$(do_facet $tgt $LR_READER $dev)
20518         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20519         echo "$out"
20520         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20521         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20522                 error "Invalid uuid returned by $LR_READER on target $tgt"
20523         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20524
20525         # check lr_reader -c on MDT0000
20526         tgt=mds1
20527         dev=$(facet_device $tgt)
20528         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20529                 skip "$LR_READER does not support additional options"
20530         fi
20531         out=$(do_facet $tgt $LR_READER -c $dev)
20532         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20533         echo "$out"
20534         num=$(echo "$out" | grep -c "mdtlov")
20535         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20536                 error "Invalid number of mdtlov clients returned by $LR_READER"
20537         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20538
20539         # check lr_reader -cr on MDT0000
20540         out=$(do_facet $tgt $LR_READER -cr $dev)
20541         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20542         echo "$out"
20543         echo "$out" | grep -q "^reply_data:$" ||
20544                 error "$LR_READER should have returned 'reply_data' section"
20545         num=$(echo "$out" | grep -c "client_generation")
20546         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20547 }
20548 run_test 252 "check lr_reader tool"
20549
20550 test_253() {
20551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20552         remote_mds_nodsh && skip "remote MDS with nodsh"
20553         remote_mgs_nodsh && skip "remote MGS with nodsh"
20554
20555         local ostidx=0
20556         local rc=0
20557         local ost_name=$(ostname_from_index $ostidx)
20558
20559         # on the mdt's osc
20560         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20561         do_facet $SINGLEMDS $LCTL get_param -n \
20562                 osp.$mdtosc_proc1.reserved_mb_high ||
20563                 skip  "remote MDS does not support reserved_mb_high"
20564
20565         rm -rf $DIR/$tdir
20566         wait_mds_ost_sync
20567         wait_delete_completed
20568         mkdir $DIR/$tdir
20569
20570         pool_add $TESTNAME || error "Pool creation failed"
20571         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20572
20573         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20574                 error "Setstripe failed"
20575
20576         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20577
20578         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20579                     grep "watermarks")
20580         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20581
20582         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20583                         osp.$mdtosc_proc1.prealloc_status)
20584         echo "prealloc_status $oa_status"
20585
20586         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20587                 error "File creation should fail"
20588
20589         #object allocation was stopped, but we still able to append files
20590         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20591                 oflag=append || error "Append failed"
20592
20593         rm -f $DIR/$tdir/$tfile.0
20594
20595         # For this test, we want to delete the files we created to go out of
20596         # space but leave the watermark, so we remain nearly out of space
20597         ost_watermarks_enospc_delete_files $tfile $ostidx
20598
20599         wait_delete_completed
20600
20601         sleep_maxage
20602
20603         for i in $(seq 10 12); do
20604                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20605                         2>/dev/null || error "File creation failed after rm"
20606         done
20607
20608         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20609                         osp.$mdtosc_proc1.prealloc_status)
20610         echo "prealloc_status $oa_status"
20611
20612         if (( oa_status != 0 )); then
20613                 error "Object allocation still disable after rm"
20614         fi
20615 }
20616 run_test 253 "Check object allocation limit"
20617
20618 test_254() {
20619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20620         remote_mds_nodsh && skip "remote MDS with nodsh"
20621         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20622                 skip "MDS does not support changelog_size"
20623
20624         local cl_user
20625         local MDT0=$(facet_svc $SINGLEMDS)
20626
20627         changelog_register || error "changelog_register failed"
20628
20629         changelog_clear 0 || error "changelog_clear failed"
20630
20631         local size1=$(do_facet $SINGLEMDS \
20632                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20633         echo "Changelog size $size1"
20634
20635         rm -rf $DIR/$tdir
20636         $LFS mkdir -i 0 $DIR/$tdir
20637         # change something
20638         mkdir -p $DIR/$tdir/pics/2008/zachy
20639         touch $DIR/$tdir/pics/2008/zachy/timestamp
20640         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20641         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20642         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20643         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20644         rm $DIR/$tdir/pics/desktop.jpg
20645
20646         local size2=$(do_facet $SINGLEMDS \
20647                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20648         echo "Changelog size after work $size2"
20649
20650         (( $size2 > $size1 )) ||
20651                 error "new Changelog size=$size2 less than old size=$size1"
20652 }
20653 run_test 254 "Check changelog size"
20654
20655 ladvise_no_type()
20656 {
20657         local type=$1
20658         local file=$2
20659
20660         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20661                 awk -F: '{print $2}' | grep $type > /dev/null
20662         if [ $? -ne 0 ]; then
20663                 return 0
20664         fi
20665         return 1
20666 }
20667
20668 ladvise_no_ioctl()
20669 {
20670         local file=$1
20671
20672         lfs ladvise -a willread $file > /dev/null 2>&1
20673         if [ $? -eq 0 ]; then
20674                 return 1
20675         fi
20676
20677         lfs ladvise -a willread $file 2>&1 |
20678                 grep "Inappropriate ioctl for device" > /dev/null
20679         if [ $? -eq 0 ]; then
20680                 return 0
20681         fi
20682         return 1
20683 }
20684
20685 percent() {
20686         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20687 }
20688
20689 # run a random read IO workload
20690 # usage: random_read_iops <filename> <filesize> <iosize>
20691 random_read_iops() {
20692         local file=$1
20693         local fsize=$2
20694         local iosize=${3:-4096}
20695
20696         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20697                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20698 }
20699
20700 drop_file_oss_cache() {
20701         local file="$1"
20702         local nodes="$2"
20703
20704         $LFS ladvise -a dontneed $file 2>/dev/null ||
20705                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20706 }
20707
20708 ladvise_willread_performance()
20709 {
20710         local repeat=10
20711         local average_origin=0
20712         local average_cache=0
20713         local average_ladvise=0
20714
20715         for ((i = 1; i <= $repeat; i++)); do
20716                 echo "Iter $i/$repeat: reading without willread hint"
20717                 cancel_lru_locks osc
20718                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20719                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20720                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20721                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20722
20723                 cancel_lru_locks osc
20724                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20725                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20726                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20727
20728                 cancel_lru_locks osc
20729                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20730                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20731                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20732                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20733                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20734         done
20735         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20736         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20737         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20738
20739         speedup_cache=$(percent $average_cache $average_origin)
20740         speedup_ladvise=$(percent $average_ladvise $average_origin)
20741
20742         echo "Average uncached read: $average_origin"
20743         echo "Average speedup with OSS cached read: " \
20744                 "$average_cache = +$speedup_cache%"
20745         echo "Average speedup with ladvise willread: " \
20746                 "$average_ladvise = +$speedup_ladvise%"
20747
20748         local lowest_speedup=20
20749         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20750                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20751                         "got $average_cache%. Skipping ladvise willread check."
20752                 return 0
20753         fi
20754
20755         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20756         # it is still good to run until then to exercise 'ladvise willread'
20757         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20758                 [ "$ost1_FSTYPE" = "zfs" ] &&
20759                 echo "osd-zfs does not support dontneed or drop_caches" &&
20760                 return 0
20761
20762         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20763         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20764                 error_not_in_vm "Speedup with willread is less than " \
20765                         "$lowest_speedup%, got $average_ladvise%"
20766 }
20767
20768 test_255a() {
20769         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20770                 skip "lustre < 2.8.54 does not support ladvise "
20771         remote_ost_nodsh && skip "remote OST with nodsh"
20772
20773         stack_trap "rm -f $DIR/$tfile"
20774         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20775
20776         ladvise_no_type willread $DIR/$tfile &&
20777                 skip "willread ladvise is not supported"
20778
20779         ladvise_no_ioctl $DIR/$tfile &&
20780                 skip "ladvise ioctl is not supported"
20781
20782         local size_mb=100
20783         local size=$((size_mb * 1048576))
20784         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20785                 error "dd to $DIR/$tfile failed"
20786
20787         lfs ladvise -a willread $DIR/$tfile ||
20788                 error "Ladvise failed with no range argument"
20789
20790         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20791                 error "Ladvise failed with no -l or -e argument"
20792
20793         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20794                 error "Ladvise failed with only -e argument"
20795
20796         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20797                 error "Ladvise failed with only -l argument"
20798
20799         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20800                 error "End offset should not be smaller than start offset"
20801
20802         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20803                 error "End offset should not be equal to start offset"
20804
20805         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20806                 error "Ladvise failed with overflowing -s argument"
20807
20808         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20809                 error "Ladvise failed with overflowing -e argument"
20810
20811         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20812                 error "Ladvise failed with overflowing -l argument"
20813
20814         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20815                 error "Ladvise succeeded with conflicting -l and -e arguments"
20816
20817         echo "Synchronous ladvise should wait"
20818         local delay=4
20819 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20820         do_nodes $(comma_list $(osts_nodes)) \
20821                 $LCTL set_param fail_val=$delay fail_loc=0x237
20822
20823         local start_ts=$SECONDS
20824         lfs ladvise -a willread $DIR/$tfile ||
20825                 error "Ladvise failed with no range argument"
20826         local end_ts=$SECONDS
20827         local inteval_ts=$((end_ts - start_ts))
20828
20829         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20830                 error "Synchronous advice didn't wait reply"
20831         fi
20832
20833         echo "Asynchronous ladvise shouldn't wait"
20834         local start_ts=$SECONDS
20835         lfs ladvise -a willread -b $DIR/$tfile ||
20836                 error "Ladvise failed with no range argument"
20837         local end_ts=$SECONDS
20838         local inteval_ts=$((end_ts - start_ts))
20839
20840         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20841                 error "Asynchronous advice blocked"
20842         fi
20843
20844         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20845         ladvise_willread_performance
20846 }
20847 run_test 255a "check 'lfs ladvise -a willread'"
20848
20849 facet_meminfo() {
20850         local facet=$1
20851         local info=$2
20852
20853         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20854 }
20855
20856 test_255b() {
20857         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20858                 skip "lustre < 2.8.54 does not support ladvise "
20859         remote_ost_nodsh && skip "remote OST with nodsh"
20860
20861         stack_trap "rm -f $DIR/$tfile"
20862         lfs setstripe -c 1 -i 0 $DIR/$tfile
20863
20864         ladvise_no_type dontneed $DIR/$tfile &&
20865                 skip "dontneed ladvise is not supported"
20866
20867         ladvise_no_ioctl $DIR/$tfile &&
20868                 skip "ladvise ioctl is not supported"
20869
20870         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20871                 [ "$ost1_FSTYPE" = "zfs" ] &&
20872                 skip "zfs-osd does not support 'ladvise dontneed'"
20873
20874         local size_mb=100
20875         local size=$((size_mb * 1048576))
20876         # In order to prevent disturbance of other processes, only check 3/4
20877         # of the memory usage
20878         local kibibytes=$((size_mb * 1024 * 3 / 4))
20879
20880         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20881                 error "dd to $DIR/$tfile failed"
20882
20883         #force write to complete before dropping OST cache & checking memory
20884         sync
20885
20886         local total=$(facet_meminfo ost1 MemTotal)
20887         echo "Total memory: $total KiB"
20888
20889         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20890         local before_read=$(facet_meminfo ost1 Cached)
20891         echo "Cache used before read: $before_read KiB"
20892
20893         lfs ladvise -a willread $DIR/$tfile ||
20894                 error "Ladvise willread failed"
20895         local after_read=$(facet_meminfo ost1 Cached)
20896         echo "Cache used after read: $after_read KiB"
20897
20898         lfs ladvise -a dontneed $DIR/$tfile ||
20899                 error "Ladvise dontneed again failed"
20900         local no_read=$(facet_meminfo ost1 Cached)
20901         echo "Cache used after dontneed ladvise: $no_read KiB"
20902
20903         if [ $total -lt $((before_read + kibibytes)) ]; then
20904                 echo "Memory is too small, abort checking"
20905                 return 0
20906         fi
20907
20908         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20909                 error "Ladvise willread should use more memory" \
20910                         "than $kibibytes KiB"
20911         fi
20912
20913         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20914                 error "Ladvise dontneed should release more memory" \
20915                         "than $kibibytes KiB"
20916         fi
20917 }
20918 run_test 255b "check 'lfs ladvise -a dontneed'"
20919
20920 test_255c() {
20921         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20922                 skip "lustre < 2.10.50 does not support lockahead"
20923
20924         local ost1_imp=$(get_osc_import_name client ost1)
20925         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20926                          cut -d'.' -f2)
20927         local count
20928         local new_count
20929         local difference
20930         local i
20931         local rc
20932
20933         test_mkdir -p $DIR/$tdir
20934         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20935
20936         #test 10 returns only success/failure
20937         i=10
20938         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20939         rc=$?
20940         if [ $rc -eq 255 ]; then
20941                 error "Ladvise test${i} failed, ${rc}"
20942         fi
20943
20944         #test 11 counts lock enqueue requests, all others count new locks
20945         i=11
20946         count=$(do_facet ost1 \
20947                 $LCTL get_param -n ost.OSS.ost.stats)
20948         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20949
20950         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20951         rc=$?
20952         if [ $rc -eq 255 ]; then
20953                 error "Ladvise test${i} failed, ${rc}"
20954         fi
20955
20956         new_count=$(do_facet ost1 \
20957                 $LCTL get_param -n ost.OSS.ost.stats)
20958         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20959                    awk '{ print $2 }')
20960
20961         difference="$((new_count - count))"
20962         if [ $difference -ne $rc ]; then
20963                 error "Ladvise test${i}, bad enqueue count, returned " \
20964                       "${rc}, actual ${difference}"
20965         fi
20966
20967         for i in $(seq 12 21); do
20968                 # If we do not do this, we run the risk of having too many
20969                 # locks and starting lock cancellation while we are checking
20970                 # lock counts.
20971                 cancel_lru_locks osc
20972
20973                 count=$($LCTL get_param -n \
20974                        ldlm.namespaces.$imp_name.lock_unused_count)
20975
20976                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20977                 rc=$?
20978                 if [ $rc -eq 255 ]; then
20979                         error "Ladvise test ${i} failed, ${rc}"
20980                 fi
20981
20982                 new_count=$($LCTL get_param -n \
20983                        ldlm.namespaces.$imp_name.lock_unused_count)
20984                 difference="$((new_count - count))"
20985
20986                 # Test 15 output is divided by 100 to map down to valid return
20987                 if [ $i -eq 15 ]; then
20988                         rc="$((rc * 100))"
20989                 fi
20990
20991                 if [ $difference -ne $rc ]; then
20992                         error "Ladvise test ${i}, bad lock count, returned " \
20993                               "${rc}, actual ${difference}"
20994                 fi
20995         done
20996
20997         #test 22 returns only success/failure
20998         i=22
20999         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21000         rc=$?
21001         if [ $rc -eq 255 ]; then
21002                 error "Ladvise test${i} failed, ${rc}"
21003         fi
21004 }
21005 run_test 255c "suite of ladvise lockahead tests"
21006
21007 test_256() {
21008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21009         remote_mds_nodsh && skip "remote MDS with nodsh"
21010         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21011         changelog_users $SINGLEMDS | grep "^cl" &&
21012                 skip "active changelog user"
21013
21014         local cl_user
21015         local cat_sl
21016         local mdt_dev
21017
21018         mdt_dev=$(mdsdevname 1)
21019         echo $mdt_dev
21020
21021         changelog_register || error "changelog_register failed"
21022
21023         rm -rf $DIR/$tdir
21024         mkdir_on_mdt0 $DIR/$tdir
21025
21026         changelog_clear 0 || error "changelog_clear failed"
21027
21028         # change something
21029         touch $DIR/$tdir/{1..10}
21030
21031         # stop the MDT
21032         stop $SINGLEMDS || error "Fail to stop MDT"
21033
21034         # remount the MDT
21035
21036         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21037
21038         #after mount new plainllog is used
21039         touch $DIR/$tdir/{11..19}
21040         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21041         stack_trap "rm -f $tmpfile"
21042         cat_sl=$(do_facet $SINGLEMDS "sync; \
21043                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21044                  llog_reader $tmpfile | grep -c type=1064553b")
21045         do_facet $SINGLEMDS llog_reader $tmpfile
21046
21047         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21048
21049         changelog_clear 0 || error "changelog_clear failed"
21050
21051         cat_sl=$(do_facet $SINGLEMDS "sync; \
21052                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21053                  llog_reader $tmpfile | grep -c type=1064553b")
21054
21055         if (( cat_sl == 2 )); then
21056                 error "Empty plain llog was not deleted from changelog catalog"
21057         elif (( cat_sl != 1 )); then
21058                 error "Active plain llog shouldn't be deleted from catalog"
21059         fi
21060 }
21061 run_test 256 "Check llog delete for empty and not full state"
21062
21063 test_257() {
21064         remote_mds_nodsh && skip "remote MDS with nodsh"
21065         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21066                 skip "Need MDS version at least 2.8.55"
21067
21068         test_mkdir $DIR/$tdir
21069
21070         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21071                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21072         stat $DIR/$tdir
21073
21074 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21075         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21076         local facet=mds$((mdtidx + 1))
21077         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21078         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21079
21080         stop $facet || error "stop MDS failed"
21081         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21082                 error "start MDS fail"
21083         wait_recovery_complete $facet
21084 }
21085 run_test 257 "xattr locks are not lost"
21086
21087 # Verify we take the i_mutex when security requires it
21088 test_258a() {
21089 #define OBD_FAIL_IMUTEX_SEC 0x141c
21090         $LCTL set_param fail_loc=0x141c
21091         touch $DIR/$tfile
21092         chmod u+s $DIR/$tfile
21093         chmod a+rwx $DIR/$tfile
21094         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21095         RC=$?
21096         if [ $RC -ne 0 ]; then
21097                 error "error, failed to take i_mutex, rc=$?"
21098         fi
21099         rm -f $DIR/$tfile
21100 }
21101 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21102
21103 # Verify we do NOT take the i_mutex in the normal case
21104 test_258b() {
21105 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21106         $LCTL set_param fail_loc=0x141d
21107         touch $DIR/$tfile
21108         chmod a+rwx $DIR
21109         chmod a+rw $DIR/$tfile
21110         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21111         RC=$?
21112         if [ $RC -ne 0 ]; then
21113                 error "error, took i_mutex unnecessarily, rc=$?"
21114         fi
21115         rm -f $DIR/$tfile
21116
21117 }
21118 run_test 258b "verify i_mutex security behavior"
21119
21120 test_259() {
21121         local file=$DIR/$tfile
21122         local before
21123         local after
21124
21125         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21126
21127         stack_trap "rm -f $file" EXIT
21128
21129         wait_delete_completed
21130         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21131         echo "before: $before"
21132
21133         $LFS setstripe -i 0 -c 1 $file
21134         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21135         sync_all_data
21136         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21137         echo "after write: $after"
21138
21139 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21140         do_facet ost1 $LCTL set_param fail_loc=0x2301
21141         $TRUNCATE $file 0
21142         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21143         echo "after truncate: $after"
21144
21145         stop ost1
21146         do_facet ost1 $LCTL set_param fail_loc=0
21147         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21148         sleep 2
21149         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21150         echo "after restart: $after"
21151         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21152                 error "missing truncate?"
21153
21154         return 0
21155 }
21156 run_test 259 "crash at delayed truncate"
21157
21158 test_260() {
21159 #define OBD_FAIL_MDC_CLOSE               0x806
21160         $LCTL set_param fail_loc=0x80000806
21161         touch $DIR/$tfile
21162
21163 }
21164 run_test 260 "Check mdc_close fail"
21165
21166 ### Data-on-MDT sanity tests ###
21167 test_270a() {
21168         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21169                 skip "Need MDS version at least 2.10.55 for DoM"
21170
21171         # create DoM file
21172         local dom=$DIR/$tdir/dom_file
21173         local tmp=$DIR/$tdir/tmp_file
21174
21175         mkdir_on_mdt0 $DIR/$tdir
21176
21177         # basic checks for DoM component creation
21178         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21179                 error "Can set MDT layout to non-first entry"
21180
21181         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21182                 error "Can define multiple entries as MDT layout"
21183
21184         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21185
21186         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21187         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21188         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21189
21190         local mdtidx=$($LFS getstripe -m $dom)
21191         local mdtname=MDT$(printf %04x $mdtidx)
21192         local facet=mds$((mdtidx + 1))
21193         local space_check=1
21194
21195         # Skip free space checks with ZFS
21196         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21197
21198         # write
21199         sync
21200         local size_tmp=$((65536 * 3))
21201         local mdtfree1=$(do_facet $facet \
21202                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21203
21204         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21205         # check also direct IO along write
21206         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21207         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21208         sync
21209         cmp $tmp $dom || error "file data is different"
21210         [ $(stat -c%s $dom) == $size_tmp ] ||
21211                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21212         if [ $space_check == 1 ]; then
21213                 local mdtfree2=$(do_facet $facet \
21214                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21215
21216                 # increase in usage from by $size_tmp
21217                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21218                         error "MDT free space wrong after write: " \
21219                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21220         fi
21221
21222         # truncate
21223         local size_dom=10000
21224
21225         $TRUNCATE $dom $size_dom
21226         [ $(stat -c%s $dom) == $size_dom ] ||
21227                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21228         if [ $space_check == 1 ]; then
21229                 mdtfree1=$(do_facet $facet \
21230                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21231                 # decrease in usage from $size_tmp to new $size_dom
21232                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21233                   $(((size_tmp - size_dom) / 1024)) ] ||
21234                         error "MDT free space is wrong after truncate: " \
21235                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21236         fi
21237
21238         # append
21239         cat $tmp >> $dom
21240         sync
21241         size_dom=$((size_dom + size_tmp))
21242         [ $(stat -c%s $dom) == $size_dom ] ||
21243                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21244         if [ $space_check == 1 ]; then
21245                 mdtfree2=$(do_facet $facet \
21246                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21247                 # increase in usage by $size_tmp from previous
21248                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21249                         error "MDT free space is wrong after append: " \
21250                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21251         fi
21252
21253         # delete
21254         rm $dom
21255         if [ $space_check == 1 ]; then
21256                 mdtfree1=$(do_facet $facet \
21257                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21258                 # decrease in usage by $size_dom from previous
21259                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21260                         error "MDT free space is wrong after removal: " \
21261                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21262         fi
21263
21264         # combined striping
21265         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21266                 error "Can't create DoM + OST striping"
21267
21268         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21269         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21270         # check also direct IO along write
21271         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21272         sync
21273         cmp $tmp $dom || error "file data is different"
21274         [ $(stat -c%s $dom) == $size_tmp ] ||
21275                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21276         rm $dom $tmp
21277
21278         return 0
21279 }
21280 run_test 270a "DoM: basic functionality tests"
21281
21282 test_270b() {
21283         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21284                 skip "Need MDS version at least 2.10.55"
21285
21286         local dom=$DIR/$tdir/dom_file
21287         local max_size=1048576
21288
21289         mkdir -p $DIR/$tdir
21290         $LFS setstripe -E $max_size -L mdt $dom
21291
21292         # truncate over the limit
21293         $TRUNCATE $dom $(($max_size + 1)) &&
21294                 error "successful truncate over the maximum size"
21295         # write over the limit
21296         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21297                 error "successful write over the maximum size"
21298         # append over the limit
21299         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21300         echo "12345" >> $dom && error "successful append over the maximum size"
21301         rm $dom
21302
21303         return 0
21304 }
21305 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21306
21307 test_270c() {
21308         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21309                 skip "Need MDS version at least 2.10.55"
21310
21311         mkdir -p $DIR/$tdir
21312         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21313
21314         # check files inherit DoM EA
21315         touch $DIR/$tdir/first
21316         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21317                 error "bad pattern"
21318         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21319                 error "bad stripe count"
21320         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21321                 error "bad stripe size"
21322
21323         # check directory inherits DoM EA and uses it as default
21324         mkdir $DIR/$tdir/subdir
21325         touch $DIR/$tdir/subdir/second
21326         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21327                 error "bad pattern in sub-directory"
21328         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21329                 error "bad stripe count in sub-directory"
21330         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21331                 error "bad stripe size in sub-directory"
21332         return 0
21333 }
21334 run_test 270c "DoM: DoM EA inheritance tests"
21335
21336 test_270d() {
21337         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21338                 skip "Need MDS version at least 2.10.55"
21339
21340         mkdir -p $DIR/$tdir
21341         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21342
21343         # inherit default DoM striping
21344         mkdir $DIR/$tdir/subdir
21345         touch $DIR/$tdir/subdir/f1
21346
21347         # change default directory striping
21348         $LFS setstripe -c 1 $DIR/$tdir/subdir
21349         touch $DIR/$tdir/subdir/f2
21350         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21351                 error "wrong default striping in file 2"
21352         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21353                 error "bad pattern in file 2"
21354         return 0
21355 }
21356 run_test 270d "DoM: change striping from DoM to RAID0"
21357
21358 test_270e() {
21359         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21360                 skip "Need MDS version at least 2.10.55"
21361
21362         mkdir -p $DIR/$tdir/dom
21363         mkdir -p $DIR/$tdir/norm
21364         DOMFILES=20
21365         NORMFILES=10
21366         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21367         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21368
21369         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21370         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21371
21372         # find DoM files by layout
21373         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21374         [ $NUM -eq  $DOMFILES ] ||
21375                 error "lfs find -L: found $NUM, expected $DOMFILES"
21376         echo "Test 1: lfs find 20 DOM files by layout: OK"
21377
21378         # there should be 1 dir with default DOM striping
21379         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21380         [ $NUM -eq  1 ] ||
21381                 error "lfs find -L: found $NUM, expected 1 dir"
21382         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21383
21384         # find DoM files by stripe size
21385         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21386         [ $NUM -eq  $DOMFILES ] ||
21387                 error "lfs find -S: found $NUM, expected $DOMFILES"
21388         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21389
21390         # find files by stripe offset except DoM files
21391         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21392         [ $NUM -eq  $NORMFILES ] ||
21393                 error "lfs find -i: found $NUM, expected $NORMFILES"
21394         echo "Test 5: lfs find no DOM files by stripe index: OK"
21395         return 0
21396 }
21397 run_test 270e "DoM: lfs find with DoM files test"
21398
21399 test_270f() {
21400         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21401                 skip "Need MDS version at least 2.10.55"
21402
21403         local mdtname=${FSNAME}-MDT0000-mdtlov
21404         local dom=$DIR/$tdir/dom_file
21405         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21406                                                 lod.$mdtname.dom_stripesize)
21407         local dom_limit=131072
21408
21409         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21410         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21411                                                 lod.$mdtname.dom_stripesize)
21412         [ ${dom_limit} -eq ${dom_current} ] ||
21413                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21414
21415         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21416         $LFS setstripe -d $DIR/$tdir
21417         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21418                 error "Can't set directory default striping"
21419
21420         # exceed maximum stripe size
21421         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21422                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21423         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21424                 error "Able to create DoM component size more than LOD limit"
21425
21426         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21427         dom_current=$(do_facet mds1 $LCTL get_param -n \
21428                                                 lod.$mdtname.dom_stripesize)
21429         [ 0 -eq ${dom_current} ] ||
21430                 error "Can't set zero DoM stripe limit"
21431         rm $dom
21432
21433         # attempt to create DoM file on server with disabled DoM should
21434         # remove DoM entry from layout and be succeed
21435         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21436                 error "Can't create DoM file (DoM is disabled)"
21437         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21438                 error "File has DoM component while DoM is disabled"
21439         rm $dom
21440
21441         # attempt to create DoM file with only DoM stripe should return error
21442         $LFS setstripe -E $dom_limit -L mdt $dom &&
21443                 error "Able to create DoM-only file while DoM is disabled"
21444
21445         # too low values to be aligned with smallest stripe size 64K
21446         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21447         dom_current=$(do_facet mds1 $LCTL get_param -n \
21448                                                 lod.$mdtname.dom_stripesize)
21449         [ 30000 -eq ${dom_current} ] &&
21450                 error "Can set too small DoM stripe limit"
21451
21452         # 64K is a minimal stripe size in Lustre, expect limit of that size
21453         [ 65536 -eq ${dom_current} ] ||
21454                 error "Limit is not set to 64K but ${dom_current}"
21455
21456         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21457         dom_current=$(do_facet mds1 $LCTL get_param -n \
21458                                                 lod.$mdtname.dom_stripesize)
21459         echo $dom_current
21460         [ 2147483648 -eq ${dom_current} ] &&
21461                 error "Can set too large DoM stripe limit"
21462
21463         do_facet mds1 $LCTL set_param -n \
21464                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21465         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21466                 error "Can't create DoM component size after limit change"
21467         do_facet mds1 $LCTL set_param -n \
21468                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21469         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21470                 error "Can't create DoM file after limit decrease"
21471         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21472                 error "Can create big DoM component after limit decrease"
21473         touch ${dom}_def ||
21474                 error "Can't create file with old default layout"
21475
21476         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21477         return 0
21478 }
21479 run_test 270f "DoM: maximum DoM stripe size checks"
21480
21481 test_270g() {
21482         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21483                 skip "Need MDS version at least 2.13.52"
21484         local dom=$DIR/$tdir/$tfile
21485
21486         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21487         local lodname=${FSNAME}-MDT0000-mdtlov
21488
21489         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21490         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21491         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21492         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21493
21494         local dom_limit=1024
21495         local dom_threshold="50%"
21496
21497         $LFS setstripe -d $DIR/$tdir
21498         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21499                 error "Can't set directory default striping"
21500
21501         do_facet mds1 $LCTL set_param -n \
21502                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21503         # set 0 threshold and create DOM file to change tunable stripesize
21504         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21505         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21506                 error "Failed to create $dom file"
21507         # now tunable dom_cur_stripesize should reach maximum
21508         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21509                                         lod.${lodname}.dom_stripesize_cur_kb)
21510         [[ $dom_current == $dom_limit ]] ||
21511                 error "Current DOM stripesize is not maximum"
21512         rm $dom
21513
21514         # set threshold for further tests
21515         do_facet mds1 $LCTL set_param -n \
21516                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21517         echo "DOM threshold is $dom_threshold free space"
21518         local dom_def
21519         local dom_set
21520         # Spoof bfree to exceed threshold
21521         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21522         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21523         for spfree in 40 20 0 15 30 55; do
21524                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21525                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21526                         error "Failed to create $dom file"
21527                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21528                                         lod.${lodname}.dom_stripesize_cur_kb)
21529                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21530                 [[ $dom_def != $dom_current ]] ||
21531                         error "Default stripe size was not changed"
21532                 if [[ $spfree > 0 ]] ; then
21533                         dom_set=$($LFS getstripe -S $dom)
21534                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21535                                 error "DOM component size is still old"
21536                 else
21537                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21538                                 error "DoM component is set with no free space"
21539                 fi
21540                 rm $dom
21541                 dom_current=$dom_def
21542         done
21543 }
21544 run_test 270g "DoM: default DoM stripe size depends on free space"
21545
21546 test_270h() {
21547         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21548                 skip "Need MDS version at least 2.13.53"
21549
21550         local mdtname=${FSNAME}-MDT0000-mdtlov
21551         local dom=$DIR/$tdir/$tfile
21552         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21553
21554         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21555         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21556
21557         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21558         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21559                 error "can't create OST file"
21560         # mirrored file with DOM entry in the second mirror
21561         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21562                 error "can't create mirror with DoM component"
21563
21564         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21565
21566         # DOM component in the middle and has other enries in the same mirror,
21567         # should succeed but lost DoM component
21568         $LFS setstripe --copy=${dom}_1 $dom ||
21569                 error "Can't create file from OST|DOM mirror layout"
21570         # check new file has no DoM layout after all
21571         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21572                 error "File has DoM component while DoM is disabled"
21573 }
21574 run_test 270h "DoM: DoM stripe removal when disabled on server"
21575
21576 test_271a() {
21577         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21578                 skip "Need MDS version at least 2.10.55"
21579
21580         local dom=$DIR/$tdir/dom
21581
21582         mkdir -p $DIR/$tdir
21583
21584         $LFS setstripe -E 1024K -L mdt $dom
21585
21586         lctl set_param -n mdc.*.stats=clear
21587         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21588         cat $dom > /dev/null
21589         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21590         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21591         ls $dom
21592         rm -f $dom
21593 }
21594 run_test 271a "DoM: data is cached for read after write"
21595
21596 test_271b() {
21597         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21598                 skip "Need MDS version at least 2.10.55"
21599
21600         local dom=$DIR/$tdir/dom
21601
21602         mkdir -p $DIR/$tdir
21603
21604         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21605
21606         lctl set_param -n mdc.*.stats=clear
21607         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21608         cancel_lru_locks mdc
21609         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21610         # second stat to check size is cached on client
21611         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21612         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21613         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21614         rm -f $dom
21615 }
21616 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21617
21618 test_271ba() {
21619         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21620                 skip "Need MDS version at least 2.10.55"
21621
21622         local dom=$DIR/$tdir/dom
21623
21624         mkdir -p $DIR/$tdir
21625
21626         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21627
21628         lctl set_param -n mdc.*.stats=clear
21629         lctl set_param -n osc.*.stats=clear
21630         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21631         cancel_lru_locks mdc
21632         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21633         # second stat to check size is cached on client
21634         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21635         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21636         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21637         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21638         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21639         rm -f $dom
21640 }
21641 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21642
21643
21644 get_mdc_stats() {
21645         local mdtidx=$1
21646         local param=$2
21647         local mdt=MDT$(printf %04x $mdtidx)
21648
21649         if [ -z $param ]; then
21650                 lctl get_param -n mdc.*$mdt*.stats
21651         else
21652                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21653         fi
21654 }
21655
21656 test_271c() {
21657         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21658                 skip "Need MDS version at least 2.10.55"
21659
21660         local dom=$DIR/$tdir/dom
21661
21662         mkdir -p $DIR/$tdir
21663
21664         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21665
21666         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21667         local facet=mds$((mdtidx + 1))
21668
21669         cancel_lru_locks mdc
21670         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21671         createmany -o $dom 1000
21672         lctl set_param -n mdc.*.stats=clear
21673         smalliomany -w $dom 1000 200
21674         get_mdc_stats $mdtidx
21675         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21676         # Each file has 1 open, 1 IO enqueues, total 2000
21677         # but now we have also +1 getxattr for security.capability, total 3000
21678         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21679         unlinkmany $dom 1000
21680
21681         cancel_lru_locks mdc
21682         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21683         createmany -o $dom 1000
21684         lctl set_param -n mdc.*.stats=clear
21685         smalliomany -w $dom 1000 200
21686         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21687         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21688         # for OPEN and IO lock.
21689         [ $((enq - enq_2)) -ge 1000 ] ||
21690                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21691         unlinkmany $dom 1000
21692         return 0
21693 }
21694 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21695
21696 cleanup_271def_tests() {
21697         trap 0
21698         rm -f $1
21699 }
21700
21701 test_271d() {
21702         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21703                 skip "Need MDS version at least 2.10.57"
21704
21705         local dom=$DIR/$tdir/dom
21706         local tmp=$TMP/$tfile
21707         trap "cleanup_271def_tests $tmp" EXIT
21708
21709         mkdir -p $DIR/$tdir
21710
21711         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21712
21713         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21714
21715         cancel_lru_locks mdc
21716         dd if=/dev/urandom of=$tmp bs=1000 count=1
21717         dd if=$tmp of=$dom bs=1000 count=1
21718         cancel_lru_locks mdc
21719
21720         cat /etc/hosts >> $tmp
21721         lctl set_param -n mdc.*.stats=clear
21722
21723         # append data to the same file it should update local page
21724         echo "Append to the same page"
21725         cat /etc/hosts >> $dom
21726         local num=$(get_mdc_stats $mdtidx ost_read)
21727         local ra=$(get_mdc_stats $mdtidx req_active)
21728         local rw=$(get_mdc_stats $mdtidx req_waittime)
21729
21730         [ -z $num ] || error "$num READ RPC occured"
21731         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21732         echo "... DONE"
21733
21734         # compare content
21735         cmp $tmp $dom || error "file miscompare"
21736
21737         cancel_lru_locks mdc
21738         lctl set_param -n mdc.*.stats=clear
21739
21740         echo "Open and read file"
21741         cat $dom > /dev/null
21742         local num=$(get_mdc_stats $mdtidx ost_read)
21743         local ra=$(get_mdc_stats $mdtidx req_active)
21744         local rw=$(get_mdc_stats $mdtidx req_waittime)
21745
21746         [ -z $num ] || error "$num READ RPC occured"
21747         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21748         echo "... DONE"
21749
21750         # compare content
21751         cmp $tmp $dom || error "file miscompare"
21752
21753         return 0
21754 }
21755 run_test 271d "DoM: read on open (1K file in reply buffer)"
21756
21757 test_271f() {
21758         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21759                 skip "Need MDS version at least 2.10.57"
21760
21761         local dom=$DIR/$tdir/dom
21762         local tmp=$TMP/$tfile
21763         trap "cleanup_271def_tests $tmp" EXIT
21764
21765         mkdir -p $DIR/$tdir
21766
21767         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21768
21769         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21770
21771         cancel_lru_locks mdc
21772         dd if=/dev/urandom of=$tmp bs=265000 count=1
21773         dd if=$tmp of=$dom bs=265000 count=1
21774         cancel_lru_locks mdc
21775         cat /etc/hosts >> $tmp
21776         lctl set_param -n mdc.*.stats=clear
21777
21778         echo "Append to the same page"
21779         cat /etc/hosts >> $dom
21780         local num=$(get_mdc_stats $mdtidx ost_read)
21781         local ra=$(get_mdc_stats $mdtidx req_active)
21782         local rw=$(get_mdc_stats $mdtidx req_waittime)
21783
21784         [ -z $num ] || error "$num READ RPC occured"
21785         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21786         echo "... DONE"
21787
21788         # compare content
21789         cmp $tmp $dom || error "file miscompare"
21790
21791         cancel_lru_locks mdc
21792         lctl set_param -n mdc.*.stats=clear
21793
21794         echo "Open and read file"
21795         cat $dom > /dev/null
21796         local num=$(get_mdc_stats $mdtidx ost_read)
21797         local ra=$(get_mdc_stats $mdtidx req_active)
21798         local rw=$(get_mdc_stats $mdtidx req_waittime)
21799
21800         [ -z $num ] && num=0
21801         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21802         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21803         echo "... DONE"
21804
21805         # compare content
21806         cmp $tmp $dom || error "file miscompare"
21807
21808         return 0
21809 }
21810 run_test 271f "DoM: read on open (200K file and read tail)"
21811
21812 test_271g() {
21813         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21814                 skip "Skipping due to old client or server version"
21815
21816         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21817         # to get layout
21818         $CHECKSTAT -t file $DIR1/$tfile
21819
21820         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21821         MULTIOP_PID=$!
21822         sleep 1
21823         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21824         $LCTL set_param fail_loc=0x80000314
21825         rm $DIR1/$tfile || error "Unlink fails"
21826         RC=$?
21827         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21828         [ $RC -eq 0 ] || error "Failed write to stale object"
21829 }
21830 run_test 271g "Discard DoM data vs client flush race"
21831
21832 test_272a() {
21833         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21834                 skip "Need MDS version at least 2.11.50"
21835
21836         local dom=$DIR/$tdir/dom
21837         mkdir -p $DIR/$tdir
21838
21839         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21840         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21841                 error "failed to write data into $dom"
21842         local old_md5=$(md5sum $dom)
21843
21844         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21845                 error "failed to migrate to the same DoM component"
21846
21847         local new_md5=$(md5sum $dom)
21848
21849         [ "$old_md5" == "$new_md5" ] ||
21850                 error "md5sum differ: $old_md5, $new_md5"
21851
21852         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21853                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21854 }
21855 run_test 272a "DoM migration: new layout with the same DOM component"
21856
21857 test_272b() {
21858         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21859                 skip "Need MDS version at least 2.11.50"
21860
21861         local dom=$DIR/$tdir/dom
21862         mkdir -p $DIR/$tdir
21863         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21864
21865         local mdtidx=$($LFS getstripe -m $dom)
21866         local mdtname=MDT$(printf %04x $mdtidx)
21867         local facet=mds$((mdtidx + 1))
21868
21869         local mdtfree1=$(do_facet $facet \
21870                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21871         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21872                 error "failed to write data into $dom"
21873         local old_md5=$(md5sum $dom)
21874         cancel_lru_locks mdc
21875         local mdtfree1=$(do_facet $facet \
21876                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21877
21878         $LFS migrate -c2 $dom ||
21879                 error "failed to migrate to the new composite layout"
21880         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21881                 error "MDT stripe was not removed"
21882
21883         cancel_lru_locks mdc
21884         local new_md5=$(md5sum $dom)
21885         [ "$old_md5" == "$new_md5" ] ||
21886                 error "$old_md5 != $new_md5"
21887
21888         # Skip free space checks with ZFS
21889         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21890                 local mdtfree2=$(do_facet $facet \
21891                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21892                 [ $mdtfree2 -gt $mdtfree1 ] ||
21893                         error "MDT space is not freed after migration"
21894         fi
21895         return 0
21896 }
21897 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21898
21899 test_272c() {
21900         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21901                 skip "Need MDS version at least 2.11.50"
21902
21903         local dom=$DIR/$tdir/$tfile
21904         mkdir -p $DIR/$tdir
21905         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21906
21907         local mdtidx=$($LFS getstripe -m $dom)
21908         local mdtname=MDT$(printf %04x $mdtidx)
21909         local facet=mds$((mdtidx + 1))
21910
21911         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21912                 error "failed to write data into $dom"
21913         local old_md5=$(md5sum $dom)
21914         cancel_lru_locks mdc
21915         local mdtfree1=$(do_facet $facet \
21916                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21917
21918         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21919                 error "failed to migrate to the new composite layout"
21920         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21921                 error "MDT stripe was not removed"
21922
21923         cancel_lru_locks mdc
21924         local new_md5=$(md5sum $dom)
21925         [ "$old_md5" == "$new_md5" ] ||
21926                 error "$old_md5 != $new_md5"
21927
21928         # Skip free space checks with ZFS
21929         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21930                 local mdtfree2=$(do_facet $facet \
21931                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21932                 [ $mdtfree2 -gt $mdtfree1 ] ||
21933                         error "MDS space is not freed after migration"
21934         fi
21935         return 0
21936 }
21937 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21938
21939 test_272d() {
21940         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21941                 skip "Need MDS version at least 2.12.55"
21942
21943         local dom=$DIR/$tdir/$tfile
21944         mkdir -p $DIR/$tdir
21945         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21946
21947         local mdtidx=$($LFS getstripe -m $dom)
21948         local mdtname=MDT$(printf %04x $mdtidx)
21949         local facet=mds$((mdtidx + 1))
21950
21951         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21952                 error "failed to write data into $dom"
21953         local old_md5=$(md5sum $dom)
21954         cancel_lru_locks mdc
21955         local mdtfree1=$(do_facet $facet \
21956                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21957
21958         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21959                 error "failed mirroring to the new composite layout"
21960         $LFS mirror resync $dom ||
21961                 error "failed mirror resync"
21962         $LFS mirror split --mirror-id 1 -d $dom ||
21963                 error "failed mirror split"
21964
21965         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21966                 error "MDT stripe was not removed"
21967
21968         cancel_lru_locks mdc
21969         local new_md5=$(md5sum $dom)
21970         [ "$old_md5" == "$new_md5" ] ||
21971                 error "$old_md5 != $new_md5"
21972
21973         # Skip free space checks with ZFS
21974         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21975                 local mdtfree2=$(do_facet $facet \
21976                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21977                 [ $mdtfree2 -gt $mdtfree1 ] ||
21978                         error "MDS space is not freed after DOM mirror deletion"
21979         fi
21980         return 0
21981 }
21982 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21983
21984 test_272e() {
21985         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21986                 skip "Need MDS version at least 2.12.55"
21987
21988         local dom=$DIR/$tdir/$tfile
21989         mkdir -p $DIR/$tdir
21990         $LFS setstripe -c 2 $dom
21991
21992         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21993                 error "failed to write data into $dom"
21994         local old_md5=$(md5sum $dom)
21995         cancel_lru_locks mdc
21996
21997         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21998                 error "failed mirroring to the DOM layout"
21999         $LFS mirror resync $dom ||
22000                 error "failed mirror resync"
22001         $LFS mirror split --mirror-id 1 -d $dom ||
22002                 error "failed mirror split"
22003
22004         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22005                 error "MDT stripe was not removed"
22006
22007         cancel_lru_locks mdc
22008         local new_md5=$(md5sum $dom)
22009         [ "$old_md5" == "$new_md5" ] ||
22010                 error "$old_md5 != $new_md5"
22011
22012         return 0
22013 }
22014 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22015
22016 test_272f() {
22017         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22018                 skip "Need MDS version at least 2.12.55"
22019
22020         local dom=$DIR/$tdir/$tfile
22021         mkdir -p $DIR/$tdir
22022         $LFS setstripe -c 2 $dom
22023
22024         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22025                 error "failed to write data into $dom"
22026         local old_md5=$(md5sum $dom)
22027         cancel_lru_locks mdc
22028
22029         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22030                 error "failed migrating to the DOM file"
22031
22032         cancel_lru_locks mdc
22033         local new_md5=$(md5sum $dom)
22034         [ "$old_md5" != "$new_md5" ] &&
22035                 error "$old_md5 != $new_md5"
22036
22037         return 0
22038 }
22039 run_test 272f "DoM migration: OST-striped file to DOM file"
22040
22041 test_273a() {
22042         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22043                 skip "Need MDS version at least 2.11.50"
22044
22045         # Layout swap cannot be done if either file has DOM component,
22046         # this will never be supported, migration should be used instead
22047
22048         local dom=$DIR/$tdir/$tfile
22049         mkdir -p $DIR/$tdir
22050
22051         $LFS setstripe -c2 ${dom}_plain
22052         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22053         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22054                 error "can swap layout with DoM component"
22055         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22056                 error "can swap layout with DoM component"
22057
22058         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22059         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22060                 error "can swap layout with DoM component"
22061         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22062                 error "can swap layout with DoM component"
22063         return 0
22064 }
22065 run_test 273a "DoM: layout swapping should fail with DOM"
22066
22067 test_273b() {
22068         mkdir -p $DIR/$tdir
22069         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22070
22071 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22072         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22073
22074         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22075 }
22076 run_test 273b "DoM: race writeback and object destroy"
22077
22078 test_275() {
22079         remote_ost_nodsh && skip "remote OST with nodsh"
22080         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22081                 skip "Need OST version >= 2.10.57"
22082
22083         local file=$DIR/$tfile
22084         local oss
22085
22086         oss=$(comma_list $(osts_nodes))
22087
22088         dd if=/dev/urandom of=$file bs=1M count=2 ||
22089                 error "failed to create a file"
22090         cancel_lru_locks osc
22091
22092         #lock 1
22093         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22094                 error "failed to read a file"
22095
22096 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22097         $LCTL set_param fail_loc=0x8000031f
22098
22099         cancel_lru_locks osc &
22100         sleep 1
22101
22102 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22103         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22104         #IO takes another lock, but matches the PENDING one
22105         #and places it to the IO RPC
22106         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22107                 error "failed to read a file with PENDING lock"
22108 }
22109 run_test 275 "Read on a canceled duplicate lock"
22110
22111 test_276() {
22112         remote_ost_nodsh && skip "remote OST with nodsh"
22113         local pid
22114
22115         do_facet ost1 "(while true; do \
22116                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22117                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22118         pid=$!
22119
22120         for LOOP in $(seq 20); do
22121                 stop ost1
22122                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22123         done
22124         kill -9 $pid
22125         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22126                 rm $TMP/sanity_276_pid"
22127 }
22128 run_test 276 "Race between mount and obd_statfs"
22129
22130 test_277() {
22131         $LCTL set_param ldlm.namespaces.*.lru_size=0
22132         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22133         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22134                         grep ^used_mb | awk '{print $2}')
22135         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22136         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22137                 oflag=direct conv=notrunc
22138         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22139                         grep ^used_mb | awk '{print $2}')
22140         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22141 }
22142 run_test 277 "Direct IO shall drop page cache"
22143
22144 test_278() {
22145         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22146         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22147         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22148                 skip "needs the same host for mdt1 mdt2" && return
22149
22150         local pid1
22151         local pid2
22152
22153 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22154         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22155         stop mds2 &
22156         pid2=$!
22157
22158         stop mds1
22159
22160         echo "Starting MDTs"
22161         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22162         wait $pid2
22163 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22164 #will return NULL
22165         do_facet mds2 $LCTL set_param fail_loc=0
22166
22167         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22168         wait_recovery_complete mds2
22169 }
22170 run_test 278 "Race starting MDS between MDTs stop/start"
22171
22172 test_280() {
22173         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22174                 skip "Need MGS version at least 2.13.52"
22175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22176         combined_mgs_mds || skip "needs combined MGS/MDT"
22177
22178         umount_client $MOUNT
22179 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22180         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22181
22182         mount_client $MOUNT &
22183         sleep 1
22184         stop mgs || error "stop mgs failed"
22185         #for a race mgs would crash
22186         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22187         # make sure we unmount client before remounting
22188         wait
22189         umount_client $MOUNT
22190         mount_client $MOUNT || error "mount client failed"
22191 }
22192 run_test 280 "Race between MGS umount and client llog processing"
22193
22194 cleanup_test_300() {
22195         trap 0
22196         umask $SAVE_UMASK
22197 }
22198 test_striped_dir() {
22199         local mdt_index=$1
22200         local stripe_count
22201         local stripe_index
22202
22203         mkdir -p $DIR/$tdir
22204
22205         SAVE_UMASK=$(umask)
22206         trap cleanup_test_300 RETURN EXIT
22207
22208         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22209                                                 $DIR/$tdir/striped_dir ||
22210                 error "set striped dir error"
22211
22212         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22213         [ "$mode" = "755" ] || error "expect 755 got $mode"
22214
22215         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22216                 error "getdirstripe failed"
22217         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22218         if [ "$stripe_count" != "2" ]; then
22219                 error "1:stripe_count is $stripe_count, expect 2"
22220         fi
22221         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22222         if [ "$stripe_count" != "2" ]; then
22223                 error "2:stripe_count is $stripe_count, expect 2"
22224         fi
22225
22226         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22227         if [ "$stripe_index" != "$mdt_index" ]; then
22228                 error "stripe_index is $stripe_index, expect $mdt_index"
22229         fi
22230
22231         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22232                 error "nlink error after create striped dir"
22233
22234         mkdir $DIR/$tdir/striped_dir/a
22235         mkdir $DIR/$tdir/striped_dir/b
22236
22237         stat $DIR/$tdir/striped_dir/a ||
22238                 error "create dir under striped dir failed"
22239         stat $DIR/$tdir/striped_dir/b ||
22240                 error "create dir under striped dir failed"
22241
22242         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22243                 error "nlink error after mkdir"
22244
22245         rmdir $DIR/$tdir/striped_dir/a
22246         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22247                 error "nlink error after rmdir"
22248
22249         rmdir $DIR/$tdir/striped_dir/b
22250         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22251                 error "nlink error after rmdir"
22252
22253         chattr +i $DIR/$tdir/striped_dir
22254         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22255                 error "immutable flags not working under striped dir!"
22256         chattr -i $DIR/$tdir/striped_dir
22257
22258         rmdir $DIR/$tdir/striped_dir ||
22259                 error "rmdir striped dir error"
22260
22261         cleanup_test_300
22262
22263         true
22264 }
22265
22266 test_300a() {
22267         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22268                 skip "skipped for lustre < 2.7.0"
22269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22270         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22271
22272         test_striped_dir 0 || error "failed on striped dir on MDT0"
22273         test_striped_dir 1 || error "failed on striped dir on MDT0"
22274 }
22275 run_test 300a "basic striped dir sanity test"
22276
22277 test_300b() {
22278         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22279                 skip "skipped for lustre < 2.7.0"
22280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22281         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22282
22283         local i
22284         local mtime1
22285         local mtime2
22286         local mtime3
22287
22288         test_mkdir $DIR/$tdir || error "mkdir fail"
22289         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22290                 error "set striped dir error"
22291         for i in {0..9}; do
22292                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22293                 sleep 1
22294                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22295                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22296                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22297                 sleep 1
22298                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22299                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22300                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22301         done
22302         true
22303 }
22304 run_test 300b "check ctime/mtime for striped dir"
22305
22306 test_300c() {
22307         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22308                 skip "skipped for lustre < 2.7.0"
22309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22310         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22311
22312         local file_count
22313
22314         mkdir_on_mdt0 $DIR/$tdir
22315         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22316                 error "set striped dir error"
22317
22318         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22319                 error "chown striped dir failed"
22320
22321         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22322                 error "create 5k files failed"
22323
22324         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22325
22326         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22327
22328         rm -rf $DIR/$tdir
22329 }
22330 run_test 300c "chown && check ls under striped directory"
22331
22332 test_300d() {
22333         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22334                 skip "skipped for lustre < 2.7.0"
22335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22336         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22337
22338         local stripe_count
22339         local file
22340
22341         mkdir -p $DIR/$tdir
22342         $LFS setstripe -c 2 $DIR/$tdir
22343
22344         #local striped directory
22345         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22346                 error "set striped dir error"
22347         #look at the directories for debug purposes
22348         ls -l $DIR/$tdir
22349         $LFS getdirstripe $DIR/$tdir
22350         ls -l $DIR/$tdir/striped_dir
22351         $LFS getdirstripe $DIR/$tdir/striped_dir
22352         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22353                 error "create 10 files failed"
22354
22355         #remote striped directory
22356         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22357                 error "set striped dir error"
22358         #look at the directories for debug purposes
22359         ls -l $DIR/$tdir
22360         $LFS getdirstripe $DIR/$tdir
22361         ls -l $DIR/$tdir/remote_striped_dir
22362         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22363         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22364                 error "create 10 files failed"
22365
22366         for file in $(find $DIR/$tdir); do
22367                 stripe_count=$($LFS getstripe -c $file)
22368                 [ $stripe_count -eq 2 ] ||
22369                         error "wrong stripe $stripe_count for $file"
22370         done
22371
22372         rm -rf $DIR/$tdir
22373 }
22374 run_test 300d "check default stripe under striped directory"
22375
22376 test_300e() {
22377         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22378                 skip "Need MDS version at least 2.7.55"
22379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22381
22382         local stripe_count
22383         local file
22384
22385         mkdir -p $DIR/$tdir
22386
22387         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22388                 error "set striped dir error"
22389
22390         touch $DIR/$tdir/striped_dir/a
22391         touch $DIR/$tdir/striped_dir/b
22392         touch $DIR/$tdir/striped_dir/c
22393
22394         mkdir $DIR/$tdir/striped_dir/dir_a
22395         mkdir $DIR/$tdir/striped_dir/dir_b
22396         mkdir $DIR/$tdir/striped_dir/dir_c
22397
22398         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22399                 error "set striped adir under striped dir error"
22400
22401         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22402                 error "set striped bdir under striped dir error"
22403
22404         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22405                 error "set striped cdir under striped dir error"
22406
22407         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22408                 error "rename dir under striped dir fails"
22409
22410         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22411                 error "rename dir under different stripes fails"
22412
22413         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22414                 error "rename file under striped dir should succeed"
22415
22416         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22417                 error "rename dir under striped dir should succeed"
22418
22419         rm -rf $DIR/$tdir
22420 }
22421 run_test 300e "check rename under striped directory"
22422
22423 test_300f() {
22424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22425         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22426         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22427                 skip "Need MDS version at least 2.7.55"
22428
22429         local stripe_count
22430         local file
22431
22432         rm -rf $DIR/$tdir
22433         mkdir -p $DIR/$tdir
22434
22435         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22436                 error "set striped dir error"
22437
22438         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22439                 error "set striped dir error"
22440
22441         touch $DIR/$tdir/striped_dir/a
22442         mkdir $DIR/$tdir/striped_dir/dir_a
22443         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22444                 error "create striped dir under striped dir fails"
22445
22446         touch $DIR/$tdir/striped_dir1/b
22447         mkdir $DIR/$tdir/striped_dir1/dir_b
22448         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22449                 error "create striped dir under striped dir fails"
22450
22451         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22452                 error "rename dir under different striped dir should fail"
22453
22454         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22455                 error "rename striped dir under diff striped dir should fail"
22456
22457         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22458                 error "rename file under diff striped dirs fails"
22459
22460         rm -rf $DIR/$tdir
22461 }
22462 run_test 300f "check rename cross striped directory"
22463
22464 test_300_check_default_striped_dir()
22465 {
22466         local dirname=$1
22467         local default_count=$2
22468         local default_index=$3
22469         local stripe_count
22470         local stripe_index
22471         local dir_stripe_index
22472         local dir
22473
22474         echo "checking $dirname $default_count $default_index"
22475         $LFS setdirstripe -D -c $default_count -i $default_index \
22476                                 -H all_char $DIR/$tdir/$dirname ||
22477                 error "set default stripe on striped dir error"
22478         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22479         [ $stripe_count -eq $default_count ] ||
22480                 error "expect $default_count get $stripe_count for $dirname"
22481
22482         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22483         [ $stripe_index -eq $default_index ] ||
22484                 error "expect $default_index get $stripe_index for $dirname"
22485
22486         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22487                                                 error "create dirs failed"
22488
22489         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22490         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22491         for dir in $(find $DIR/$tdir/$dirname/*); do
22492                 stripe_count=$($LFS getdirstripe -c $dir)
22493                 (( $stripe_count == $default_count )) ||
22494                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22495                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22496                 error "stripe count $default_count != $stripe_count for $dir"
22497
22498                 stripe_index=$($LFS getdirstripe -i $dir)
22499                 [ $default_index -eq -1 ] ||
22500                         [ $stripe_index -eq $default_index ] ||
22501                         error "$stripe_index != $default_index for $dir"
22502
22503                 #check default stripe
22504                 stripe_count=$($LFS getdirstripe -D -c $dir)
22505                 [ $stripe_count -eq $default_count ] ||
22506                 error "default count $default_count != $stripe_count for $dir"
22507
22508                 stripe_index=$($LFS getdirstripe -D -i $dir)
22509                 [ $stripe_index -eq $default_index ] ||
22510                 error "default index $default_index != $stripe_index for $dir"
22511         done
22512         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22513 }
22514
22515 test_300g() {
22516         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22517         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22518                 skip "Need MDS version at least 2.7.55"
22519
22520         local dir
22521         local stripe_count
22522         local stripe_index
22523
22524         mkdir_on_mdt0 $DIR/$tdir
22525         mkdir $DIR/$tdir/normal_dir
22526
22527         #Checking when client cache stripe index
22528         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22529         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22530                 error "create striped_dir failed"
22531
22532         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22533                 error "create dir0 fails"
22534         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22535         [ $stripe_index -eq 0 ] ||
22536                 error "dir0 expect index 0 got $stripe_index"
22537
22538         mkdir $DIR/$tdir/striped_dir/dir1 ||
22539                 error "create dir1 fails"
22540         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22541         [ $stripe_index -eq 1 ] ||
22542                 error "dir1 expect index 1 got $stripe_index"
22543
22544         #check default stripe count/stripe index
22545         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22546         test_300_check_default_striped_dir normal_dir 1 0
22547         test_300_check_default_striped_dir normal_dir -1 1
22548         test_300_check_default_striped_dir normal_dir 2 -1
22549
22550         #delete default stripe information
22551         echo "delete default stripeEA"
22552         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22553                 error "set default stripe on striped dir error"
22554
22555         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22556         for dir in $(find $DIR/$tdir/normal_dir/*); do
22557                 stripe_count=$($LFS getdirstripe -c $dir)
22558                 [ $stripe_count -eq 0 ] ||
22559                         error "expect 1 get $stripe_count for $dir"
22560                 stripe_index=$($LFS getdirstripe -i $dir)
22561                 [ $stripe_index -eq 0 ] ||
22562                         error "expect 0 get $stripe_index for $dir"
22563         done
22564 }
22565 run_test 300g "check default striped directory for normal directory"
22566
22567 test_300h() {
22568         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22569         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22570                 skip "Need MDS version at least 2.7.55"
22571
22572         local dir
22573         local stripe_count
22574
22575         mkdir $DIR/$tdir
22576         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22577                 error "set striped dir error"
22578
22579         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22580         test_300_check_default_striped_dir striped_dir 1 0
22581         test_300_check_default_striped_dir striped_dir -1 1
22582         test_300_check_default_striped_dir striped_dir 2 -1
22583
22584         #delete default stripe information
22585         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22586                 error "set default stripe on striped dir error"
22587
22588         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22589         for dir in $(find $DIR/$tdir/striped_dir/*); do
22590                 stripe_count=$($LFS getdirstripe -c $dir)
22591                 [ $stripe_count -eq 0 ] ||
22592                         error "expect 1 get $stripe_count for $dir"
22593         done
22594 }
22595 run_test 300h "check default striped directory for striped directory"
22596
22597 test_300i() {
22598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22599         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22600         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22601                 skip "Need MDS version at least 2.7.55"
22602
22603         local stripe_count
22604         local file
22605
22606         mkdir $DIR/$tdir
22607
22608         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22609                 error "set striped dir error"
22610
22611         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22612                 error "create files under striped dir failed"
22613
22614         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22615                 error "set striped hashdir error"
22616
22617         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22618                 error "create dir0 under hash dir failed"
22619         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22620                 error "create dir1 under hash dir failed"
22621         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22622                 error "create dir2 under hash dir failed"
22623
22624         # unfortunately, we need to umount to clear dir layout cache for now
22625         # once we fully implement dir layout, we can drop this
22626         umount_client $MOUNT || error "umount failed"
22627         mount_client $MOUNT || error "mount failed"
22628
22629         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22630         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22631         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22632
22633         #set the stripe to be unknown hash type
22634         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22635         $LCTL set_param fail_loc=0x1901
22636         for ((i = 0; i < 10; i++)); do
22637                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22638                         error "stat f-$i failed"
22639                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22640         done
22641
22642         touch $DIR/$tdir/striped_dir/f0 &&
22643                 error "create under striped dir with unknown hash should fail"
22644
22645         $LCTL set_param fail_loc=0
22646
22647         umount_client $MOUNT || error "umount failed"
22648         mount_client $MOUNT || error "mount failed"
22649
22650         return 0
22651 }
22652 run_test 300i "client handle unknown hash type striped directory"
22653
22654 test_300j() {
22655         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22657         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22658                 skip "Need MDS version at least 2.7.55"
22659
22660         local stripe_count
22661         local file
22662
22663         mkdir $DIR/$tdir
22664
22665         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22666         $LCTL set_param fail_loc=0x1702
22667         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22668                 error "set striped dir error"
22669
22670         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22671                 error "create files under striped dir failed"
22672
22673         $LCTL set_param fail_loc=0
22674
22675         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22676
22677         return 0
22678 }
22679 run_test 300j "test large update record"
22680
22681 test_300k() {
22682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22683         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22684         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22685                 skip "Need MDS version at least 2.7.55"
22686
22687         # this test needs a huge transaction
22688         local kb
22689         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22690              osd*.$FSNAME-MDT0000.kbytestotal")
22691         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22692
22693         local stripe_count
22694         local file
22695
22696         mkdir $DIR/$tdir
22697
22698         #define OBD_FAIL_LARGE_STRIPE   0x1703
22699         $LCTL set_param fail_loc=0x1703
22700         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22701                 error "set striped dir error"
22702         $LCTL set_param fail_loc=0
22703
22704         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22705                 error "getstripeddir fails"
22706         rm -rf $DIR/$tdir/striped_dir ||
22707                 error "unlink striped dir fails"
22708
22709         return 0
22710 }
22711 run_test 300k "test large striped directory"
22712
22713 test_300l() {
22714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22715         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22716         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22717                 skip "Need MDS version at least 2.7.55"
22718
22719         local stripe_index
22720
22721         test_mkdir -p $DIR/$tdir/striped_dir
22722         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22723                         error "chown $RUNAS_ID failed"
22724         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22725                 error "set default striped dir failed"
22726
22727         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22728         $LCTL set_param fail_loc=0x80000158
22729         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22730
22731         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22732         [ $stripe_index -eq 1 ] ||
22733                 error "expect 1 get $stripe_index for $dir"
22734 }
22735 run_test 300l "non-root user to create dir under striped dir with stale layout"
22736
22737 test_300m() {
22738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22739         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22740         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22741                 skip "Need MDS version at least 2.7.55"
22742
22743         mkdir -p $DIR/$tdir/striped_dir
22744         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22745                 error "set default stripes dir error"
22746
22747         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22748
22749         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22750         [ $stripe_count -eq 0 ] ||
22751                         error "expect 0 get $stripe_count for a"
22752
22753         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22754                 error "set default stripes dir error"
22755
22756         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22757
22758         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22759         [ $stripe_count -eq 0 ] ||
22760                         error "expect 0 get $stripe_count for b"
22761
22762         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22763                 error "set default stripes dir error"
22764
22765         mkdir $DIR/$tdir/striped_dir/c &&
22766                 error "default stripe_index is invalid, mkdir c should fails"
22767
22768         rm -rf $DIR/$tdir || error "rmdir fails"
22769 }
22770 run_test 300m "setstriped directory on single MDT FS"
22771
22772 cleanup_300n() {
22773         local list=$(comma_list $(mdts_nodes))
22774
22775         trap 0
22776         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22777 }
22778
22779 test_300n() {
22780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22781         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22782         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22783                 skip "Need MDS version at least 2.7.55"
22784         remote_mds_nodsh && skip "remote MDS with nodsh"
22785
22786         local stripe_index
22787         local list=$(comma_list $(mdts_nodes))
22788
22789         trap cleanup_300n RETURN EXIT
22790         mkdir -p $DIR/$tdir
22791         chmod 777 $DIR/$tdir
22792         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22793                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22794                 error "create striped dir succeeds with gid=0"
22795
22796         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22797         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22798                 error "create striped dir fails with gid=-1"
22799
22800         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22801         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22802                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22803                 error "set default striped dir succeeds with gid=0"
22804
22805
22806         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22807         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22808                 error "set default striped dir fails with gid=-1"
22809
22810
22811         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22812         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22813                                         error "create test_dir fails"
22814         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22815                                         error "create test_dir1 fails"
22816         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22817                                         error "create test_dir2 fails"
22818         cleanup_300n
22819 }
22820 run_test 300n "non-root user to create dir under striped dir with default EA"
22821
22822 test_300o() {
22823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22824         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22825         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22826                 skip "Need MDS version at least 2.7.55"
22827
22828         local numfree1
22829         local numfree2
22830
22831         mkdir -p $DIR/$tdir
22832
22833         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22834         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22835         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22836                 skip "not enough free inodes $numfree1 $numfree2"
22837         fi
22838
22839         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22840         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22841         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22842                 skip "not enough free space $numfree1 $numfree2"
22843         fi
22844
22845         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22846                 error "setdirstripe fails"
22847
22848         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22849                 error "create dirs fails"
22850
22851         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22852         ls $DIR/$tdir/striped_dir > /dev/null ||
22853                 error "ls striped dir fails"
22854         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22855                 error "unlink big striped dir fails"
22856 }
22857 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22858
22859 test_300p() {
22860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22861         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22862         remote_mds_nodsh && skip "remote MDS with nodsh"
22863
22864         mkdir_on_mdt0 $DIR/$tdir
22865
22866         #define OBD_FAIL_OUT_ENOSPC     0x1704
22867         do_facet mds2 lctl set_param fail_loc=0x80001704
22868         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22869                  && error "create striped directory should fail"
22870
22871         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22872
22873         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22874         true
22875 }
22876 run_test 300p "create striped directory without space"
22877
22878 test_300q() {
22879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22880         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22881
22882         local fd=$(free_fd)
22883         local cmd="exec $fd<$tdir"
22884         cd $DIR
22885         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22886         eval $cmd
22887         cmd="exec $fd<&-"
22888         trap "eval $cmd" EXIT
22889         cd $tdir || error "cd $tdir fails"
22890         rmdir  ../$tdir || error "rmdir $tdir fails"
22891         mkdir local_dir && error "create dir succeeds"
22892         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22893         eval $cmd
22894         return 0
22895 }
22896 run_test 300q "create remote directory under orphan directory"
22897
22898 test_300r() {
22899         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22900                 skip "Need MDS version at least 2.7.55" && return
22901         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22902
22903         mkdir $DIR/$tdir
22904
22905         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22906                 error "set striped dir error"
22907
22908         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22909                 error "getstripeddir fails"
22910
22911         local stripe_count
22912         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22913                       awk '/lmv_stripe_count:/ { print $2 }')
22914
22915         [ $MDSCOUNT -ne $stripe_count ] &&
22916                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22917
22918         rm -rf $DIR/$tdir/striped_dir ||
22919                 error "unlink striped dir fails"
22920 }
22921 run_test 300r "test -1 striped directory"
22922
22923 test_300s_helper() {
22924         local count=$1
22925
22926         local stripe_dir=$DIR/$tdir/striped_dir.$count
22927
22928         $LFS mkdir -c $count $stripe_dir ||
22929                 error "lfs mkdir -c error"
22930
22931         $LFS getdirstripe $stripe_dir ||
22932                 error "lfs getdirstripe fails"
22933
22934         local stripe_count
22935         stripe_count=$($LFS getdirstripe $stripe_dir |
22936                       awk '/lmv_stripe_count:/ { print $2 }')
22937
22938         [ $count -ne $stripe_count ] &&
22939                 error_noexit "bad stripe count $stripe_count expected $count"
22940
22941         local dupe_stripes
22942         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22943                 awk '/0x/ {count[$1] += 1}; END {
22944                         for (idx in count) {
22945                                 if (count[idx]>1) {
22946                                         print "index " idx " count " count[idx]
22947                                 }
22948                         }
22949                 }')
22950
22951         if [[ -n "$dupe_stripes" ]] ; then
22952                 lfs getdirstripe $stripe_dir
22953                 error_noexit "Dupe MDT above: $dupe_stripes "
22954         fi
22955
22956         rm -rf $stripe_dir ||
22957                 error_noexit "unlink $stripe_dir fails"
22958 }
22959
22960 test_300s() {
22961         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22962                 skip "Need MDS version at least 2.7.55" && return
22963         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22964
22965         mkdir $DIR/$tdir
22966         for count in $(seq 2 $MDSCOUNT); do
22967                 test_300s_helper $count
22968         done
22969 }
22970 run_test 300s "test lfs mkdir -c without -i"
22971
22972
22973 prepare_remote_file() {
22974         mkdir $DIR/$tdir/src_dir ||
22975                 error "create remote source failed"
22976
22977         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22978                  error "cp to remote source failed"
22979         touch $DIR/$tdir/src_dir/a
22980
22981         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22982                 error "create remote target dir failed"
22983
22984         touch $DIR/$tdir/tgt_dir/b
22985
22986         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22987                 error "rename dir cross MDT failed!"
22988
22989         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22990                 error "src_child still exists after rename"
22991
22992         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22993                 error "missing file(a) after rename"
22994
22995         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22996                 error "diff after rename"
22997 }
22998
22999 test_310a() {
23000         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23002
23003         local remote_file=$DIR/$tdir/tgt_dir/b
23004
23005         mkdir -p $DIR/$tdir
23006
23007         prepare_remote_file || error "prepare remote file failed"
23008
23009         #open-unlink file
23010         $OPENUNLINK $remote_file $remote_file ||
23011                 error "openunlink $remote_file failed"
23012         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23013 }
23014 run_test 310a "open unlink remote file"
23015
23016 test_310b() {
23017         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23019
23020         local remote_file=$DIR/$tdir/tgt_dir/b
23021
23022         mkdir -p $DIR/$tdir
23023
23024         prepare_remote_file || error "prepare remote file failed"
23025
23026         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23027         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23028         $CHECKSTAT -t file $remote_file || error "check file failed"
23029 }
23030 run_test 310b "unlink remote file with multiple links while open"
23031
23032 test_310c() {
23033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23034         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23035
23036         local remote_file=$DIR/$tdir/tgt_dir/b
23037
23038         mkdir -p $DIR/$tdir
23039
23040         prepare_remote_file || error "prepare remote file failed"
23041
23042         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23043         multiop_bg_pause $remote_file O_uc ||
23044                         error "mulitop failed for remote file"
23045         MULTIPID=$!
23046         $MULTIOP $DIR/$tfile Ouc
23047         kill -USR1 $MULTIPID
23048         wait $MULTIPID
23049 }
23050 run_test 310c "open-unlink remote file with multiple links"
23051
23052 #LU-4825
23053 test_311() {
23054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23055         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23056         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23057                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23058         remote_mds_nodsh && skip "remote MDS with nodsh"
23059
23060         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23061         local mdts=$(comma_list $(mdts_nodes))
23062
23063         mkdir -p $DIR/$tdir
23064         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23065         createmany -o $DIR/$tdir/$tfile. 1000
23066
23067         # statfs data is not real time, let's just calculate it
23068         old_iused=$((old_iused + 1000))
23069
23070         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23071                         osp.*OST0000*MDT0000.create_count")
23072         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23073                                 osp.*OST0000*MDT0000.max_create_count")
23074         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23075
23076         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23077         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23078         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23079
23080         unlinkmany $DIR/$tdir/$tfile. 1000
23081
23082         do_nodes $mdts "$LCTL set_param -n \
23083                         osp.*OST0000*.max_create_count=$max_count"
23084         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23085                 do_nodes $mdts "$LCTL set_param -n \
23086                                 osp.*OST0000*.create_count=$count"
23087         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23088                         grep "=0" && error "create_count is zero"
23089
23090         local new_iused
23091         for i in $(seq 120); do
23092                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23093                 # system may be too busy to destroy all objs in time, use
23094                 # a somewhat small value to not fail autotest
23095                 [ $((old_iused - new_iused)) -gt 400 ] && break
23096                 sleep 1
23097         done
23098
23099         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23100         [ $((old_iused - new_iused)) -gt 400 ] ||
23101                 error "objs not destroyed after unlink"
23102 }
23103 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23104
23105 zfs_oid_to_objid()
23106 {
23107         local ost=$1
23108         local objid=$2
23109
23110         local vdevdir=$(dirname $(facet_vdevice $ost))
23111         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23112         local zfs_zapid=$(do_facet $ost $cmd |
23113                           grep -w "/O/0/d$((objid%32))" -C 5 |
23114                           awk '/Object/{getline; print $1}')
23115         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23116                           awk "/$objid = /"'{printf $3}')
23117
23118         echo $zfs_objid
23119 }
23120
23121 zfs_object_blksz() {
23122         local ost=$1
23123         local objid=$2
23124
23125         local vdevdir=$(dirname $(facet_vdevice $ost))
23126         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23127         local blksz=$(do_facet $ost $cmd $objid |
23128                       awk '/dblk/{getline; printf $4}')
23129
23130         case "${blksz: -1}" in
23131                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23132                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23133                 *) ;;
23134         esac
23135
23136         echo $blksz
23137 }
23138
23139 test_312() { # LU-4856
23140         remote_ost_nodsh && skip "remote OST with nodsh"
23141         [ "$ost1_FSTYPE" = "zfs" ] ||
23142                 skip_env "the test only applies to zfs"
23143
23144         local max_blksz=$(do_facet ost1 \
23145                           $ZFS get -p recordsize $(facet_device ost1) |
23146                           awk '!/VALUE/{print $3}')
23147
23148         # to make life a little bit easier
23149         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23150         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23151
23152         local tf=$DIR/$tdir/$tfile
23153         touch $tf
23154         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23155
23156         # Get ZFS object id
23157         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23158         # block size change by sequential overwrite
23159         local bs
23160
23161         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23162                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23163
23164                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23165                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23166         done
23167         rm -f $tf
23168
23169         # block size change by sequential append write
23170         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23171         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23172         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23173         local count
23174
23175         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23176                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23177                         oflag=sync conv=notrunc
23178
23179                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23180                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23181                         error "blksz error, actual $blksz, " \
23182                                 "expected: 2 * $count * $PAGE_SIZE"
23183         done
23184         rm -f $tf
23185
23186         # random write
23187         touch $tf
23188         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23189         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23190
23191         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23192         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23193         [ $blksz -eq $PAGE_SIZE ] ||
23194                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23195
23196         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23197         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23198         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23199
23200         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23201         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23202         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23203 }
23204 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23205
23206 test_313() {
23207         remote_ost_nodsh && skip "remote OST with nodsh"
23208
23209         local file=$DIR/$tfile
23210
23211         rm -f $file
23212         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23213
23214         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23215         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23216         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23217                 error "write should failed"
23218         do_facet ost1 "$LCTL set_param fail_loc=0"
23219         rm -f $file
23220 }
23221 run_test 313 "io should fail after last_rcvd update fail"
23222
23223 test_314() {
23224         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23225
23226         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23227         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23228         rm -f $DIR/$tfile
23229         wait_delete_completed
23230         do_facet ost1 "$LCTL set_param fail_loc=0"
23231 }
23232 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23233
23234 test_315() { # LU-618
23235         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23236
23237         local file=$DIR/$tfile
23238         rm -f $file
23239
23240         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23241                 error "multiop file write failed"
23242         $MULTIOP $file oO_RDONLY:r4063232_c &
23243         PID=$!
23244
23245         sleep 2
23246
23247         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23248         kill -USR1 $PID
23249
23250         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23251         rm -f $file
23252 }
23253 run_test 315 "read should be accounted"
23254
23255 test_316() {
23256         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23257         large_xattr_enabled || skip_env "ea_inode feature disabled"
23258
23259         rm -rf $DIR/$tdir/d
23260         mkdir -p $DIR/$tdir/d
23261         chown nobody $DIR/$tdir/d
23262         touch $DIR/$tdir/d/file
23263
23264         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23265 }
23266 run_test 316 "lfs mv"
23267
23268 test_317() {
23269         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23270                 skip "Need MDS version at least 2.11.53"
23271         if [ "$ost1_FSTYPE" == "zfs" ]; then
23272                 skip "LU-10370: no implementation for ZFS"
23273         fi
23274
23275         local trunc_sz
23276         local grant_blk_size
23277
23278         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23279                         awk '/grant_block_size:/ { print $2; exit; }')
23280         #
23281         # Create File of size 5M. Truncate it to below size's and verify
23282         # blocks count.
23283         #
23284         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23285                 error "Create file $DIR/$tfile failed"
23286         stack_trap "rm -f $DIR/$tfile" EXIT
23287
23288         for trunc_sz in 2097152 4097 4000 509 0; do
23289                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23290                         error "truncate $tfile to $trunc_sz failed"
23291                 local sz=$(stat --format=%s $DIR/$tfile)
23292                 local blk=$(stat --format=%b $DIR/$tfile)
23293                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23294                                      grant_blk_size) * 8))
23295
23296                 if [[ $blk -ne $trunc_blk ]]; then
23297                         $(which stat) $DIR/$tfile
23298                         error "Expected Block $trunc_blk got $blk for $tfile"
23299                 fi
23300
23301                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23302                         error "Expected Size $trunc_sz got $sz for $tfile"
23303         done
23304
23305         #
23306         # sparse file test
23307         # Create file with a hole and write actual two blocks. Block count
23308         # must be 16.
23309         #
23310         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23311                 conv=fsync || error "Create file : $DIR/$tfile"
23312
23313         # Calculate the final truncate size.
23314         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23315
23316         #
23317         # truncate to size $trunc_sz bytes. Strip the last block
23318         # The block count must drop to 8
23319         #
23320         $TRUNCATE $DIR/$tfile $trunc_sz ||
23321                 error "truncate $tfile to $trunc_sz failed"
23322
23323         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23324         sz=$(stat --format=%s $DIR/$tfile)
23325         blk=$(stat --format=%b $DIR/$tfile)
23326
23327         if [[ $blk -ne $trunc_bsz ]]; then
23328                 $(which stat) $DIR/$tfile
23329                 error "Expected Block $trunc_bsz got $blk for $tfile"
23330         fi
23331
23332         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23333                 error "Expected Size $trunc_sz got $sz for $tfile"
23334 }
23335 run_test 317 "Verify blocks get correctly update after truncate"
23336
23337 test_318() {
23338         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23339         local old_max_active=$($LCTL get_param -n \
23340                             ${llite_name}.max_read_ahead_async_active \
23341                             2>/dev/null)
23342
23343         $LCTL set_param llite.*.max_read_ahead_async_active=256
23344         local max_active=$($LCTL get_param -n \
23345                            ${llite_name}.max_read_ahead_async_active \
23346                            2>/dev/null)
23347         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23348
23349         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23350                 error "set max_read_ahead_async_active should succeed"
23351
23352         $LCTL set_param llite.*.max_read_ahead_async_active=512
23353         max_active=$($LCTL get_param -n \
23354                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23355         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23356
23357         # restore @max_active
23358         [ $old_max_active -ne 0 ] && $LCTL set_param \
23359                 llite.*.max_read_ahead_async_active=$old_max_active
23360
23361         local old_threshold=$($LCTL get_param -n \
23362                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23363         local max_per_file_mb=$($LCTL get_param -n \
23364                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23365
23366         local invalid=$(($max_per_file_mb + 1))
23367         $LCTL set_param \
23368                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23369                         && error "set $invalid should fail"
23370
23371         local valid=$(($invalid - 1))
23372         $LCTL set_param \
23373                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23374                         error "set $valid should succeed"
23375         local threshold=$($LCTL get_param -n \
23376                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23377         [ $threshold -eq $valid ] || error \
23378                 "expect threshold $valid got $threshold"
23379         $LCTL set_param \
23380                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23381 }
23382 run_test 318 "Verify async readahead tunables"
23383
23384 test_319() {
23385         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23386
23387         local before=$(date +%s)
23388         local evict
23389         local mdir=$DIR/$tdir
23390         local file=$mdir/xxx
23391
23392         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23393         touch $file
23394
23395 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23396         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23397         $LFS mv -m1 $file &
23398
23399         sleep 1
23400         dd if=$file of=/dev/null
23401         wait
23402         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23403           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23404
23405         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23406 }
23407 run_test 319 "lost lease lock on migrate error"
23408
23409 test_398a() { # LU-4198
23410         local ost1_imp=$(get_osc_import_name client ost1)
23411         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23412                          cut -d'.' -f2)
23413
23414         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23415         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23416
23417         # request a new lock on client
23418         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23419
23420         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23421         local lock_count=$($LCTL get_param -n \
23422                            ldlm.namespaces.$imp_name.lru_size)
23423         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23424
23425         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23426
23427         # no lock cached, should use lockless IO and not enqueue new lock
23428         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23429         lock_count=$($LCTL get_param -n \
23430                      ldlm.namespaces.$imp_name.lru_size)
23431         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23432 }
23433 run_test 398a "direct IO should cancel lock otherwise lockless"
23434
23435 test_398b() { # LU-4198
23436         which fio || skip_env "no fio installed"
23437         $LFS setstripe -c -1 $DIR/$tfile
23438
23439         local size=12
23440         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23441
23442         local njobs=4
23443         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23444         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23445                 --numjobs=$njobs --fallocate=none \
23446                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23447                 --filename=$DIR/$tfile &
23448         bg_pid=$!
23449
23450         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23451         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23452                 --numjobs=$njobs --fallocate=none \
23453                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23454                 --filename=$DIR/$tfile || true
23455         wait $bg_pid
23456
23457         rm -f $DIR/$tfile
23458 }
23459 run_test 398b "DIO and buffer IO race"
23460
23461 test_398c() { # LU-4198
23462         local ost1_imp=$(get_osc_import_name client ost1)
23463         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23464                          cut -d'.' -f2)
23465
23466         which fio || skip_env "no fio installed"
23467
23468         saved_debug=$($LCTL get_param -n debug)
23469         $LCTL set_param debug=0
23470
23471         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23472         ((size /= 1024)) # by megabytes
23473         ((size /= 2)) # write half of the OST at most
23474         [ $size -gt 40 ] && size=40 #reduce test time anyway
23475
23476         $LFS setstripe -c 1 $DIR/$tfile
23477
23478         # it seems like ldiskfs reserves more space than necessary if the
23479         # writing blocks are not mapped, so it extends the file firstly
23480         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23481         cancel_lru_locks osc
23482
23483         # clear and verify rpc_stats later
23484         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23485
23486         local njobs=4
23487         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23488         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23489                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23490                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23491                 --filename=$DIR/$tfile
23492         [ $? -eq 0 ] || error "fio write error"
23493
23494         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23495                 error "Locks were requested while doing AIO"
23496
23497         # get the percentage of 1-page I/O
23498         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23499                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23500                 awk '{print $7}')
23501         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23502
23503         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23504         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23505                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23506                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23507                 --filename=$DIR/$tfile
23508         [ $? -eq 0 ] || error "fio mixed read write error"
23509
23510         echo "AIO with large block size ${size}M"
23511         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23512                 --numjobs=1 --fallocate=none --ioengine=libaio \
23513                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23514                 --filename=$DIR/$tfile
23515         [ $? -eq 0 ] || error "fio large block size failed"
23516
23517         rm -f $DIR/$tfile
23518         $LCTL set_param debug="$saved_debug"
23519 }
23520 run_test 398c "run fio to test AIO"
23521
23522 test_398d() { #  LU-13846
23523         which aiocp || skip_env "no aiocp installed"
23524         local aio_file=$DIR/$tfile.aio
23525
23526         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23527
23528         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23529         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23530         stack_trap "rm -f $DIR/$tfile $aio_file"
23531
23532         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23533
23534         # make sure we don't crash and fail properly
23535         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23536                 error "aio not aligned with PAGE SIZE should fail"
23537
23538         rm -f $DIR/$tfile $aio_file
23539 }
23540 run_test 398d "run aiocp to verify block size > stripe size"
23541
23542 test_398e() {
23543         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23544         touch $DIR/$tfile.new
23545         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23546 }
23547 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23548
23549 test_398f() { #  LU-14687
23550         which aiocp || skip_env "no aiocp installed"
23551         local aio_file=$DIR/$tfile.aio
23552
23553         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23554
23555         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23556         stack_trap "rm -f $DIR/$tfile $aio_file"
23557
23558         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23559         $LCTL set_param fail_loc=0x1418
23560         # make sure we don't crash and fail properly
23561         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23562                 error "aio with page allocation failure succeeded"
23563         $LCTL set_param fail_loc=0
23564         diff $DIR/$tfile $aio_file
23565         [[ $? != 0 ]] || error "no diff after failed aiocp"
23566 }
23567 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23568
23569 test_fake_rw() {
23570         local read_write=$1
23571         if [ "$read_write" = "write" ]; then
23572                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23573         elif [ "$read_write" = "read" ]; then
23574                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23575         else
23576                 error "argument error"
23577         fi
23578
23579         # turn off debug for performance testing
23580         local saved_debug=$($LCTL get_param -n debug)
23581         $LCTL set_param debug=0
23582
23583         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23584
23585         # get ost1 size - $FSNAME-OST0000
23586         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23587         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23588         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23589
23590         if [ "$read_write" = "read" ]; then
23591                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23592         fi
23593
23594         local start_time=$(date +%s.%N)
23595         $dd_cmd bs=1M count=$blocks oflag=sync ||
23596                 error "real dd $read_write error"
23597         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23598
23599         if [ "$read_write" = "write" ]; then
23600                 rm -f $DIR/$tfile
23601         fi
23602
23603         # define OBD_FAIL_OST_FAKE_RW           0x238
23604         do_facet ost1 $LCTL set_param fail_loc=0x238
23605
23606         local start_time=$(date +%s.%N)
23607         $dd_cmd bs=1M count=$blocks oflag=sync ||
23608                 error "fake dd $read_write error"
23609         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23610
23611         if [ "$read_write" = "write" ]; then
23612                 # verify file size
23613                 cancel_lru_locks osc
23614                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23615                         error "$tfile size not $blocks MB"
23616         fi
23617         do_facet ost1 $LCTL set_param fail_loc=0
23618
23619         echo "fake $read_write $duration_fake vs. normal $read_write" \
23620                 "$duration in seconds"
23621         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23622                 error_not_in_vm "fake write is slower"
23623
23624         $LCTL set_param -n debug="$saved_debug"
23625         rm -f $DIR/$tfile
23626 }
23627 test_399a() { # LU-7655 for OST fake write
23628         remote_ost_nodsh && skip "remote OST with nodsh"
23629
23630         test_fake_rw write
23631 }
23632 run_test 399a "fake write should not be slower than normal write"
23633
23634 test_399b() { # LU-8726 for OST fake read
23635         remote_ost_nodsh && skip "remote OST with nodsh"
23636         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23637                 skip_env "ldiskfs only test"
23638         fi
23639
23640         test_fake_rw read
23641 }
23642 run_test 399b "fake read should not be slower than normal read"
23643
23644 test_400a() { # LU-1606, was conf-sanity test_74
23645         if ! which $CC > /dev/null 2>&1; then
23646                 skip_env "$CC is not installed"
23647         fi
23648
23649         local extra_flags=''
23650         local out=$TMP/$tfile
23651         local prefix=/usr/include/lustre
23652         local prog
23653
23654         # Oleg removes c files in his test rig so test if any c files exist
23655         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23656                 skip_env "Needed c test files are missing"
23657
23658         if ! [[ -d $prefix ]]; then
23659                 # Assume we're running in tree and fixup the include path.
23660                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23661                 extra_flags+=" -L$LUSTRE/utils/.lib"
23662         fi
23663
23664         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23665                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23666                         error "client api broken"
23667         done
23668         rm -f $out
23669 }
23670 run_test 400a "Lustre client api program can compile and link"
23671
23672 test_400b() { # LU-1606, LU-5011
23673         local header
23674         local out=$TMP/$tfile
23675         local prefix=/usr/include/linux/lustre
23676
23677         # We use a hard coded prefix so that this test will not fail
23678         # when run in tree. There are headers in lustre/include/lustre/
23679         # that are not packaged (like lustre_idl.h) and have more
23680         # complicated include dependencies (like config.h and lnet/types.h).
23681         # Since this test about correct packaging we just skip them when
23682         # they don't exist (see below) rather than try to fixup cppflags.
23683
23684         if ! which $CC > /dev/null 2>&1; then
23685                 skip_env "$CC is not installed"
23686         fi
23687
23688         for header in $prefix/*.h; do
23689                 if ! [[ -f "$header" ]]; then
23690                         continue
23691                 fi
23692
23693                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23694                         continue # lustre_ioctl.h is internal header
23695                 fi
23696
23697                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23698                         error "cannot compile '$header'"
23699         done
23700         rm -f $out
23701 }
23702 run_test 400b "packaged headers can be compiled"
23703
23704 test_401a() { #LU-7437
23705         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23706         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23707
23708         #count the number of parameters by "list_param -R"
23709         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23710         #count the number of parameters by listing proc files
23711         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23712         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23713         echo "proc_dirs='$proc_dirs'"
23714         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23715         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23716                       sort -u | wc -l)
23717
23718         [ $params -eq $procs ] ||
23719                 error "found $params parameters vs. $procs proc files"
23720
23721         # test the list_param -D option only returns directories
23722         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23723         #count the number of parameters by listing proc directories
23724         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23725                 sort -u | wc -l)
23726
23727         [ $params -eq $procs ] ||
23728                 error "found $params parameters vs. $procs proc files"
23729 }
23730 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23731
23732 test_401b() {
23733         # jobid_var may not allow arbitrary values, so use jobid_name
23734         # if available
23735         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23736                 local testname=jobid_name tmp='testing%p'
23737         else
23738                 local testname=jobid_var tmp=testing
23739         fi
23740
23741         local save=$($LCTL get_param -n $testname)
23742
23743         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23744                 error "no error returned when setting bad parameters"
23745
23746         local jobid_new=$($LCTL get_param -n foe $testname baz)
23747         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23748
23749         $LCTL set_param -n fog=bam $testname=$save bat=fog
23750         local jobid_old=$($LCTL get_param -n foe $testname bag)
23751         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23752 }
23753 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23754
23755 test_401c() {
23756         # jobid_var may not allow arbitrary values, so use jobid_name
23757         # if available
23758         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23759                 local testname=jobid_name
23760         else
23761                 local testname=jobid_var
23762         fi
23763
23764         local jobid_var_old=$($LCTL get_param -n $testname)
23765         local jobid_var_new
23766
23767         $LCTL set_param $testname= &&
23768                 error "no error returned for 'set_param a='"
23769
23770         jobid_var_new=$($LCTL get_param -n $testname)
23771         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23772                 error "$testname was changed by setting without value"
23773
23774         $LCTL set_param $testname &&
23775                 error "no error returned for 'set_param a'"
23776
23777         jobid_var_new=$($LCTL get_param -n $testname)
23778         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23779                 error "$testname was changed by setting without value"
23780 }
23781 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23782
23783 test_401d() {
23784         # jobid_var may not allow arbitrary values, so use jobid_name
23785         # if available
23786         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23787                 local testname=jobid_name new_value='foo=bar%p'
23788         else
23789                 local testname=jobid_var new_valuie=foo=bar
23790         fi
23791
23792         local jobid_var_old=$($LCTL get_param -n $testname)
23793         local jobid_var_new
23794
23795         $LCTL set_param $testname=$new_value ||
23796                 error "'set_param a=b' did not accept a value containing '='"
23797
23798         jobid_var_new=$($LCTL get_param -n $testname)
23799         [[ "$jobid_var_new" == "$new_value" ]] ||
23800                 error "'set_param a=b' failed on a value containing '='"
23801
23802         # Reset the $testname to test the other format
23803         $LCTL set_param $testname=$jobid_var_old
23804         jobid_var_new=$($LCTL get_param -n $testname)
23805         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23806                 error "failed to reset $testname"
23807
23808         $LCTL set_param $testname $new_value ||
23809                 error "'set_param a b' did not accept a value containing '='"
23810
23811         jobid_var_new=$($LCTL get_param -n $testname)
23812         [[ "$jobid_var_new" == "$new_value" ]] ||
23813                 error "'set_param a b' failed on a value containing '='"
23814
23815         $LCTL set_param $testname $jobid_var_old
23816         jobid_var_new=$($LCTL get_param -n $testname)
23817         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23818                 error "failed to reset $testname"
23819 }
23820 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23821
23822 test_402() {
23823         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23824         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23825                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23826         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23827                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23828                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23829         remote_mds_nodsh && skip "remote MDS with nodsh"
23830
23831         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23832 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23833         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23834         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23835                 echo "Touch failed - OK"
23836 }
23837 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23838
23839 test_403() {
23840         local file1=$DIR/$tfile.1
23841         local file2=$DIR/$tfile.2
23842         local tfile=$TMP/$tfile
23843
23844         rm -f $file1 $file2 $tfile
23845
23846         touch $file1
23847         ln $file1 $file2
23848
23849         # 30 sec OBD_TIMEOUT in ll_getattr()
23850         # right before populating st_nlink
23851         $LCTL set_param fail_loc=0x80001409
23852         stat -c %h $file1 > $tfile &
23853
23854         # create an alias, drop all locks and reclaim the dentry
23855         < $file2
23856         cancel_lru_locks mdc
23857         cancel_lru_locks osc
23858         sysctl -w vm.drop_caches=2
23859
23860         wait
23861
23862         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23863
23864         rm -f $tfile $file1 $file2
23865 }
23866 run_test 403 "i_nlink should not drop to zero due to aliasing"
23867
23868 test_404() { # LU-6601
23869         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23870                 skip "Need server version newer than 2.8.52"
23871         remote_mds_nodsh && skip "remote MDS with nodsh"
23872
23873         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23874                 awk '/osp .*-osc-MDT/ { print $4}')
23875
23876         local osp
23877         for osp in $mosps; do
23878                 echo "Deactivate: " $osp
23879                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23880                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23881                         awk -vp=$osp '$4 == p { print $2 }')
23882                 [ $stat = IN ] || {
23883                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23884                         error "deactivate error"
23885                 }
23886                 echo "Activate: " $osp
23887                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23888                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23889                         awk -vp=$osp '$4 == p { print $2 }')
23890                 [ $stat = UP ] || {
23891                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23892                         error "activate error"
23893                 }
23894         done
23895 }
23896 run_test 404 "validate manual {de}activated works properly for OSPs"
23897
23898 test_405() {
23899         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23900         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23901                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23902                         skip "Layout swap lock is not supported"
23903
23904         check_swap_layouts_support
23905         check_swap_layout_no_dom $DIR
23906
23907         test_mkdir $DIR/$tdir
23908         swap_lock_test -d $DIR/$tdir ||
23909                 error "One layout swap locked test failed"
23910 }
23911 run_test 405 "Various layout swap lock tests"
23912
23913 test_406() {
23914         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23915         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23916         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23918         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23919                 skip "Need MDS version at least 2.8.50"
23920
23921         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23922         local test_pool=$TESTNAME
23923
23924         pool_add $test_pool || error "pool_add failed"
23925         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23926                 error "pool_add_targets failed"
23927
23928         save_layout_restore_at_exit $MOUNT
23929
23930         # parent set default stripe count only, child will stripe from both
23931         # parent and fs default
23932         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23933                 error "setstripe $MOUNT failed"
23934         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23935         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23936         for i in $(seq 10); do
23937                 local f=$DIR/$tdir/$tfile.$i
23938                 touch $f || error "touch failed"
23939                 local count=$($LFS getstripe -c $f)
23940                 [ $count -eq $OSTCOUNT ] ||
23941                         error "$f stripe count $count != $OSTCOUNT"
23942                 local offset=$($LFS getstripe -i $f)
23943                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23944                 local size=$($LFS getstripe -S $f)
23945                 [ $size -eq $((def_stripe_size * 2)) ] ||
23946                         error "$f stripe size $size != $((def_stripe_size * 2))"
23947                 local pool=$($LFS getstripe -p $f)
23948                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23949         done
23950
23951         # change fs default striping, delete parent default striping, now child
23952         # will stripe from new fs default striping only
23953         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23954                 error "change $MOUNT default stripe failed"
23955         $LFS setstripe -c 0 $DIR/$tdir ||
23956                 error "delete $tdir default stripe failed"
23957         for i in $(seq 11 20); do
23958                 local f=$DIR/$tdir/$tfile.$i
23959                 touch $f || error "touch $f failed"
23960                 local count=$($LFS getstripe -c $f)
23961                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23962                 local offset=$($LFS getstripe -i $f)
23963                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23964                 local size=$($LFS getstripe -S $f)
23965                 [ $size -eq $def_stripe_size ] ||
23966                         error "$f stripe size $size != $def_stripe_size"
23967                 local pool=$($LFS getstripe -p $f)
23968                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23969         done
23970
23971         unlinkmany $DIR/$tdir/$tfile. 1 20
23972
23973         local f=$DIR/$tdir/$tfile
23974         pool_remove_all_targets $test_pool $f
23975         pool_remove $test_pool $f
23976 }
23977 run_test 406 "DNE support fs default striping"
23978
23979 test_407() {
23980         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23981         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23982                 skip "Need MDS version at least 2.8.55"
23983         remote_mds_nodsh && skip "remote MDS with nodsh"
23984
23985         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23986                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23987         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23988                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23989         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23990
23991         #define OBD_FAIL_DT_TXN_STOP    0x2019
23992         for idx in $(seq $MDSCOUNT); do
23993                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23994         done
23995         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23996         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23997                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23998         true
23999 }
24000 run_test 407 "transaction fail should cause operation fail"
24001
24002 test_408() {
24003         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24004
24005         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24006         lctl set_param fail_loc=0x8000040a
24007         # let ll_prepare_partial_page() fail
24008         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24009
24010         rm -f $DIR/$tfile
24011
24012         # create at least 100 unused inodes so that
24013         # shrink_icache_memory(0) should not return 0
24014         touch $DIR/$tfile-{0..100}
24015         rm -f $DIR/$tfile-{0..100}
24016         sync
24017
24018         echo 2 > /proc/sys/vm/drop_caches
24019 }
24020 run_test 408 "drop_caches should not hang due to page leaks"
24021
24022 test_409()
24023 {
24024         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24025
24026         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24027         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24028         touch $DIR/$tdir/guard || error "(2) Fail to create"
24029
24030         local PREFIX=$(str_repeat 'A' 128)
24031         echo "Create 1K hard links start at $(date)"
24032         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24033                 error "(3) Fail to hard link"
24034
24035         echo "Links count should be right although linkEA overflow"
24036         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24037         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24038         [ $linkcount -eq 1001 ] ||
24039                 error "(5) Unexpected hard links count: $linkcount"
24040
24041         echo "List all links start at $(date)"
24042         ls -l $DIR/$tdir/foo > /dev/null ||
24043                 error "(6) Fail to list $DIR/$tdir/foo"
24044
24045         echo "Unlink hard links start at $(date)"
24046         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24047                 error "(7) Fail to unlink"
24048         echo "Unlink hard links finished at $(date)"
24049 }
24050 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24051
24052 test_410()
24053 {
24054         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24055                 skip "Need client version at least 2.9.59"
24056         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24057                 skip "Need MODULES build"
24058
24059         # Create a file, and stat it from the kernel
24060         local testfile=$DIR/$tfile
24061         touch $testfile
24062
24063         local run_id=$RANDOM
24064         local my_ino=$(stat --format "%i" $testfile)
24065
24066         # Try to insert the module. This will always fail as the
24067         # module is designed to not be inserted.
24068         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24069             &> /dev/null
24070
24071         # Anything but success is a test failure
24072         dmesg | grep -q \
24073             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24074             error "no inode match"
24075 }
24076 run_test 410 "Test inode number returned from kernel thread"
24077
24078 cleanup_test411_cgroup() {
24079         trap 0
24080         rmdir "$1"
24081 }
24082
24083 test_411() {
24084         local cg_basedir=/sys/fs/cgroup/memory
24085         # LU-9966
24086         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24087                 skip "no setup for cgroup"
24088
24089         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24090                 error "test file creation failed"
24091         cancel_lru_locks osc
24092
24093         # Create a very small memory cgroup to force a slab allocation error
24094         local cgdir=$cg_basedir/osc_slab_alloc
24095         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24096         trap "cleanup_test411_cgroup $cgdir" EXIT
24097         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24098         echo 1M > $cgdir/memory.limit_in_bytes
24099
24100         # Should not LBUG, just be killed by oom-killer
24101         # dd will return 0 even allocation failure in some environment.
24102         # So don't check return value
24103         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24104         cleanup_test411_cgroup $cgdir
24105
24106         return 0
24107 }
24108 run_test 411 "Slab allocation error with cgroup does not LBUG"
24109
24110 test_412() {
24111         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24112         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24113                 skip "Need server version at least 2.10.55"
24114         fi
24115
24116         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24117                 error "mkdir failed"
24118         $LFS getdirstripe $DIR/$tdir
24119         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24120         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24121                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24122         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24123         [ $stripe_count -eq 2 ] ||
24124                 error "expect 2 get $stripe_count"
24125 }
24126 run_test 412 "mkdir on specific MDTs"
24127
24128 test_qos_mkdir() {
24129         local mkdir_cmd=$1
24130         local stripe_count=$2
24131         local mdts=$(comma_list $(mdts_nodes))
24132
24133         local testdir
24134         local lmv_qos_prio_free
24135         local lmv_qos_threshold_rr
24136         local lmv_qos_maxage
24137         local lod_qos_prio_free
24138         local lod_qos_threshold_rr
24139         local lod_qos_maxage
24140         local count
24141         local i
24142
24143         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24144         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24145         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24146                 head -n1)
24147         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24148         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24149         stack_trap "$LCTL set_param \
24150                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
24151         stack_trap "$LCTL set_param \
24152                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
24153         stack_trap "$LCTL set_param \
24154                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
24155
24156         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24157                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24158         lod_qos_prio_free=${lod_qos_prio_free%%%}
24159         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24160                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24161         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24162         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24163                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24164         stack_trap "do_nodes $mdts $LCTL set_param \
24165                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
24166         stack_trap "do_nodes $mdts $LCTL set_param \
24167                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
24168                 EXIT
24169         stack_trap "do_nodes $mdts $LCTL set_param \
24170                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
24171
24172         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24173         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24174
24175         testdir=$DIR/$tdir-s$stripe_count/rr
24176
24177         local stripe_index=$($LFS getstripe -m $testdir)
24178         local test_mkdir_rr=true
24179
24180         getfattr -d -m dmv $testdir | grep dmv
24181         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
24182                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
24183
24184                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
24185         fi
24186
24187         echo
24188         $test_mkdir_rr &&
24189                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24190                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24191
24192         for i in $(seq $((100 * MDSCOUNT))); do
24193                 eval $mkdir_cmd $testdir/subdir$i ||
24194                         error "$mkdir_cmd subdir$i failed"
24195         done
24196
24197         for i in $(seq $MDSCOUNT); do
24198                 count=$($LFS getdirstripe -i $testdir/* |
24199                                 grep ^$((i - 1))$ | wc -l)
24200                 echo "$count directories created on MDT$((i - 1))"
24201                 if $test_mkdir_rr; then
24202                         (( $count == 100 )) ||
24203                                 error "subdirs are not evenly distributed"
24204                 elif [ $((i - 1)) -eq $stripe_index ]; then
24205                         (( $count == 100 * MDSCOUNT )) ||
24206                                 error "$count subdirs created on MDT$((i - 1))"
24207                 else
24208                         (( $count == 0 )) ||
24209                                 error "$count subdirs created on MDT$((i - 1))"
24210                 fi
24211
24212                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24213                         count=$($LFS getdirstripe $testdir/* |
24214                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24215                         echo "$count stripes created on MDT$((i - 1))"
24216                         # deviation should < 5% of average
24217                         (( $count < 95 * stripe_count )) ||
24218                         (( $count > 105 * stripe_count)) &&
24219                                 error "stripes are not evenly distributed"
24220                 fi
24221         done
24222
24223         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
24224         do_nodes $mdts $LCTL set_param \
24225                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
24226
24227         echo
24228         echo "Check for uneven MDTs: "
24229
24230         local ffree
24231         local bavail
24232         local max
24233         local min
24234         local max_index
24235         local min_index
24236         local tmp
24237
24238         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24239         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24240         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24241
24242         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24243         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24244         max_index=0
24245         min_index=0
24246         for ((i = 1; i < ${#ffree[@]}; i++)); do
24247                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24248                 if [ $tmp -gt $max ]; then
24249                         max=$tmp
24250                         max_index=$i
24251                 fi
24252                 if [ $tmp -lt $min ]; then
24253                         min=$tmp
24254                         min_index=$i
24255                 fi
24256         done
24257
24258         (( ${ffree[min_index]} == 0 )) &&
24259                 skip "no free files in MDT$min_index"
24260         (( ${ffree[min_index]} > 100000000 )) &&
24261                 skip "too many free files in MDT$min_index"
24262
24263         # Check if we need to generate uneven MDTs
24264         local threshold=50
24265         local diff=$(((max - min) * 100 / min))
24266         local value="$(generate_string 1024)"
24267
24268         while [ $diff -lt $threshold ]; do
24269                 # generate uneven MDTs, create till $threshold% diff
24270                 echo -n "weight diff=$diff% must be > $threshold% ..."
24271                 count=$((${ffree[min_index]} / 10))
24272                 # 50 sec per 10000 files in vm
24273                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
24274                         skip "$count files to create"
24275                 echo "Fill MDT$min_index with $count files"
24276                 [ -d $DIR/$tdir-MDT$min_index ] ||
24277                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
24278                         error "mkdir $tdir-MDT$min_index failed"
24279                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
24280                         error "create d$count failed"
24281
24282                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24283                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24284                 max=$(((${ffree[max_index]} >> 8) * \
24285                         (${bavail[max_index]} * bsize >> 16)))
24286                 min=$(((${ffree[min_index]} >> 8) * \
24287                         (${bavail[min_index]} * bsize >> 16)))
24288                 diff=$(((max - min) * 100 / min))
24289         done
24290
24291         echo "MDT filesfree available: ${ffree[@]}"
24292         echo "MDT blocks available: ${bavail[@]}"
24293         echo "weight diff=$diff%"
24294
24295         echo
24296         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24297
24298         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24299         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24300         # decrease statfs age, so that it can be updated in time
24301         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24302         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24303
24304         sleep 1
24305
24306         testdir=$DIR/$tdir-s$stripe_count/qos
24307
24308         for i in $(seq $((100 * MDSCOUNT))); do
24309                 eval $mkdir_cmd $testdir/subdir$i ||
24310                         error "$mkdir_cmd subdir$i failed"
24311         done
24312
24313         for i in $(seq $MDSCOUNT); do
24314                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24315                         wc -l)
24316                 echo "$count directories created on MDT$((i - 1))"
24317
24318                 if [ $stripe_count -gt 1 ]; then
24319                         count=$($LFS getdirstripe $testdir/* |
24320                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24321                         echo "$count stripes created on MDT$((i - 1))"
24322                 fi
24323         done
24324
24325         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24326         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24327
24328         # D-value should > 10% of averge
24329         (( $max - $min < 10 )) &&
24330                 error "subdirs shouldn't be evenly distributed"
24331
24332         # ditto
24333         if [ $stripe_count -gt 1 ]; then
24334                 max=$($LFS getdirstripe $testdir/* |
24335                         grep -P "^\s+$max_index\t" | wc -l)
24336                 min=$($LFS getdirstripe $testdir/* |
24337                         grep -P "^\s+$min_index\t" | wc -l)
24338                 (( $max - $min < 10 * $stripe_count )) &&
24339                         error "stripes shouldn't be evenly distributed"|| true
24340         fi
24341 }
24342
24343 test_413a() {
24344         [ $MDSCOUNT -lt 2 ] &&
24345                 skip "We need at least 2 MDTs for this test"
24346
24347         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24348                 skip "Need server version at least 2.12.52"
24349
24350         local stripe_count
24351
24352         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24353                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24354                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24355                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24356                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24357         done
24358 }
24359 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24360
24361 test_413b() {
24362         [ $MDSCOUNT -lt 2 ] &&
24363                 skip "We need at least 2 MDTs for this test"
24364
24365         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24366                 skip "Need server version at least 2.12.52"
24367
24368         local testdir
24369         local stripe_count
24370
24371         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24372                 testdir=$DIR/$tdir-s$stripe_count
24373                 mkdir $testdir || error "mkdir $testdir failed"
24374                 mkdir $testdir/rr || error "mkdir rr failed"
24375                 mkdir $testdir/qos || error "mkdir qos failed"
24376                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24377                         $testdir/rr || error "setdirstripe rr failed"
24378                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24379                         error "setdirstripe failed"
24380                 test_qos_mkdir "mkdir" $stripe_count
24381         done
24382 }
24383 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24384
24385 test_413c() {
24386         [ $MDSCOUNT -ge 2 ] ||
24387                 skip "We need at least 2 MDTs for this test"
24388
24389         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24390                 skip "Need server version at least 2.14.50"
24391
24392         local testdir
24393         local inherit
24394         local inherit_rr
24395
24396         testdir=$DIR/${tdir}-s1
24397         mkdir $testdir || error "mkdir $testdir failed"
24398         mkdir $testdir/rr || error "mkdir rr failed"
24399         mkdir $testdir/qos || error "mkdir qos failed"
24400         # default max_inherit is -1, default max_inherit_rr is 0
24401         $LFS setdirstripe -D -c 1 $testdir/rr ||
24402                 error "setdirstripe rr failed"
24403         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24404                 error "setdirstripe qos failed"
24405         test_qos_mkdir "mkdir" 1
24406
24407         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24408         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24409         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24410         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24411         (( $inherit_rr == 0 )) ||
24412                 error "rr/level1 inherit-rr $inherit_rr != 0"
24413
24414         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24415         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24416         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24417         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24418         (( $inherit_rr == 0 )) ||
24419                 error "qos/level1 inherit-rr $inherit_rr !=0"
24420         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24421         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24422                 error "level2 shouldn't have default LMV" || true
24423 }
24424 run_test 413c "mkdir with default LMV max inherit rr"
24425
24426 test_414() {
24427 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24428         $LCTL set_param fail_loc=0x80000521
24429         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24430         rm -f $DIR/$tfile
24431 }
24432 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24433
24434 test_415() {
24435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24436         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24437                 skip "Need server version at least 2.11.52"
24438
24439         # LU-11102
24440         local total
24441         local setattr_pid
24442         local start_time
24443         local end_time
24444         local duration
24445
24446         total=500
24447         # this test may be slow on ZFS
24448         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24449
24450         # though this test is designed for striped directory, let's test normal
24451         # directory too since lock is always saved as CoS lock.
24452         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24453         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24454
24455         (
24456                 while true; do
24457                         touch $DIR/$tdir
24458                 done
24459         ) &
24460         setattr_pid=$!
24461
24462         start_time=$(date +%s)
24463         for i in $(seq $total); do
24464                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24465                         > /dev/null
24466         done
24467         end_time=$(date +%s)
24468         duration=$((end_time - start_time))
24469
24470         kill -9 $setattr_pid
24471
24472         echo "rename $total files took $duration sec"
24473         [ $duration -lt 100 ] || error "rename took $duration sec"
24474 }
24475 run_test 415 "lock revoke is not missing"
24476
24477 test_416() {
24478         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24479                 skip "Need server version at least 2.11.55"
24480
24481         # define OBD_FAIL_OSD_TXN_START    0x19a
24482         do_facet mds1 lctl set_param fail_loc=0x19a
24483
24484         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24485
24486         true
24487 }
24488 run_test 416 "transaction start failure won't cause system hung"
24489
24490 cleanup_417() {
24491         trap 0
24492         do_nodes $(comma_list $(mdts_nodes)) \
24493                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24494         do_nodes $(comma_list $(mdts_nodes)) \
24495                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24496         do_nodes $(comma_list $(mdts_nodes)) \
24497                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24498 }
24499
24500 test_417() {
24501         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24502         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24503                 skip "Need MDS version at least 2.11.56"
24504
24505         trap cleanup_417 RETURN EXIT
24506
24507         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24508         do_nodes $(comma_list $(mdts_nodes)) \
24509                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24510         $LFS migrate -m 0 $DIR/$tdir.1 &&
24511                 error "migrate dir $tdir.1 should fail"
24512
24513         do_nodes $(comma_list $(mdts_nodes)) \
24514                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24515         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24516                 error "create remote dir $tdir.2 should fail"
24517
24518         do_nodes $(comma_list $(mdts_nodes)) \
24519                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24520         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24521                 error "create striped dir $tdir.3 should fail"
24522         true
24523 }
24524 run_test 417 "disable remote dir, striped dir and dir migration"
24525
24526 # Checks that the outputs of df [-i] and lfs df [-i] match
24527 #
24528 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24529 check_lfs_df() {
24530         local dir=$2
24531         local inodes
24532         local df_out
24533         local lfs_df_out
24534         local count
24535         local passed=false
24536
24537         # blocks or inodes
24538         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24539
24540         for count in {1..100}; do
24541                 cancel_lru_locks
24542                 sync; sleep 0.2
24543
24544                 # read the lines of interest
24545                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24546                         error "df $inodes $dir | tail -n +2 failed"
24547                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24548                         error "lfs df $inodes $dir | grep summary: failed"
24549
24550                 # skip first substrings of each output as they are different
24551                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24552                 # compare the two outputs
24553                 passed=true
24554                 for i in {1..5}; do
24555                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24556                 done
24557                 $passed && break
24558         done
24559
24560         if ! $passed; then
24561                 df -P $inodes $dir
24562                 echo
24563                 lfs df $inodes $dir
24564                 error "df and lfs df $1 output mismatch: "      \
24565                       "df ${inodes}: ${df_out[*]}, "            \
24566                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24567         fi
24568 }
24569
24570 test_418() {
24571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24572
24573         local dir=$DIR/$tdir
24574         local numfiles=$((RANDOM % 4096 + 2))
24575         local numblocks=$((RANDOM % 256 + 1))
24576
24577         wait_delete_completed
24578         test_mkdir $dir
24579
24580         # check block output
24581         check_lfs_df blocks $dir
24582         # check inode output
24583         check_lfs_df inodes $dir
24584
24585         # create a single file and retest
24586         echo "Creating a single file and testing"
24587         createmany -o $dir/$tfile- 1 &>/dev/null ||
24588                 error "creating 1 file in $dir failed"
24589         check_lfs_df blocks $dir
24590         check_lfs_df inodes $dir
24591
24592         # create a random number of files
24593         echo "Creating $((numfiles - 1)) files and testing"
24594         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24595                 error "creating $((numfiles - 1)) files in $dir failed"
24596
24597         # write a random number of blocks to the first test file
24598         echo "Writing $numblocks 4K blocks and testing"
24599         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24600                 count=$numblocks &>/dev/null ||
24601                 error "dd to $dir/${tfile}-0 failed"
24602
24603         # retest
24604         check_lfs_df blocks $dir
24605         check_lfs_df inodes $dir
24606
24607         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24608                 error "unlinking $numfiles files in $dir failed"
24609 }
24610 run_test 418 "df and lfs df outputs match"
24611
24612 test_419()
24613 {
24614         local dir=$DIR/$tdir
24615
24616         mkdir -p $dir
24617         touch $dir/file
24618
24619         cancel_lru_locks mdc
24620
24621         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24622         $LCTL set_param fail_loc=0x1410
24623         cat $dir/file
24624         $LCTL set_param fail_loc=0
24625         rm -rf $dir
24626 }
24627 run_test 419 "Verify open file by name doesn't crash kernel"
24628
24629 test_420()
24630 {
24631         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24632                 skip "Need MDS version at least 2.12.53"
24633
24634         local SAVE_UMASK=$(umask)
24635         local dir=$DIR/$tdir
24636         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24637
24638         mkdir -p $dir
24639         umask 0000
24640         mkdir -m03777 $dir/testdir
24641         ls -dn $dir/testdir
24642         # Need to remove trailing '.' when SELinux is enabled
24643         local dirperms=$(ls -dn $dir/testdir |
24644                          awk '{ sub(/\.$/, "", $1); print $1}')
24645         [ $dirperms == "drwxrwsrwt" ] ||
24646                 error "incorrect perms on $dir/testdir"
24647
24648         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24649                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24650         ls -n $dir/testdir/testfile
24651         local fileperms=$(ls -n $dir/testdir/testfile |
24652                           awk '{ sub(/\.$/, "", $1); print $1}')
24653         [ $fileperms == "-rwxr-xr-x" ] ||
24654                 error "incorrect perms on $dir/testdir/testfile"
24655
24656         umask $SAVE_UMASK
24657 }
24658 run_test 420 "clear SGID bit on non-directories for non-members"
24659
24660 test_421a() {
24661         local cnt
24662         local fid1
24663         local fid2
24664
24665         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24666                 skip "Need MDS version at least 2.12.54"
24667
24668         test_mkdir $DIR/$tdir
24669         createmany -o $DIR/$tdir/f 3
24670         cnt=$(ls -1 $DIR/$tdir | wc -l)
24671         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24672
24673         fid1=$(lfs path2fid $DIR/$tdir/f1)
24674         fid2=$(lfs path2fid $DIR/$tdir/f2)
24675         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24676
24677         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24678         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24679
24680         cnt=$(ls -1 $DIR/$tdir | wc -l)
24681         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24682
24683         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24684         createmany -o $DIR/$tdir/f 3
24685         cnt=$(ls -1 $DIR/$tdir | wc -l)
24686         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24687
24688         fid1=$(lfs path2fid $DIR/$tdir/f1)
24689         fid2=$(lfs path2fid $DIR/$tdir/f2)
24690         echo "remove using fsname $FSNAME"
24691         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24692
24693         cnt=$(ls -1 $DIR/$tdir | wc -l)
24694         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24695 }
24696 run_test 421a "simple rm by fid"
24697
24698 test_421b() {
24699         local cnt
24700         local FID1
24701         local FID2
24702
24703         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24704                 skip "Need MDS version at least 2.12.54"
24705
24706         test_mkdir $DIR/$tdir
24707         createmany -o $DIR/$tdir/f 3
24708         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24709         MULTIPID=$!
24710
24711         FID1=$(lfs path2fid $DIR/$tdir/f1)
24712         FID2=$(lfs path2fid $DIR/$tdir/f2)
24713         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24714
24715         kill -USR1 $MULTIPID
24716         wait
24717
24718         cnt=$(ls $DIR/$tdir | wc -l)
24719         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24720 }
24721 run_test 421b "rm by fid on open file"
24722
24723 test_421c() {
24724         local cnt
24725         local FIDS
24726
24727         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24728                 skip "Need MDS version at least 2.12.54"
24729
24730         test_mkdir $DIR/$tdir
24731         createmany -o $DIR/$tdir/f 3
24732         touch $DIR/$tdir/$tfile
24733         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24734         cnt=$(ls -1 $DIR/$tdir | wc -l)
24735         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24736
24737         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24738         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24739
24740         cnt=$(ls $DIR/$tdir | wc -l)
24741         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24742 }
24743 run_test 421c "rm by fid against hardlinked files"
24744
24745 test_421d() {
24746         local cnt
24747         local FIDS
24748
24749         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24750                 skip "Need MDS version at least 2.12.54"
24751
24752         test_mkdir $DIR/$tdir
24753         createmany -o $DIR/$tdir/f 4097
24754         cnt=$(ls -1 $DIR/$tdir | wc -l)
24755         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24756
24757         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24758         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24759
24760         cnt=$(ls $DIR/$tdir | wc -l)
24761         rm -rf $DIR/$tdir
24762         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24763 }
24764 run_test 421d "rmfid en masse"
24765
24766 test_421e() {
24767         local cnt
24768         local FID
24769
24770         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24771         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24772                 skip "Need MDS version at least 2.12.54"
24773
24774         mkdir -p $DIR/$tdir
24775         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24776         createmany -o $DIR/$tdir/striped_dir/f 512
24777         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24778         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24779
24780         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24781                 sed "s/[/][^:]*://g")
24782         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24783
24784         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24785         rm -rf $DIR/$tdir
24786         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24787 }
24788 run_test 421e "rmfid in DNE"
24789
24790 test_421f() {
24791         local cnt
24792         local FID
24793
24794         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24795                 skip "Need MDS version at least 2.12.54"
24796
24797         test_mkdir $DIR/$tdir
24798         touch $DIR/$tdir/f
24799         cnt=$(ls -1 $DIR/$tdir | wc -l)
24800         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24801
24802         FID=$(lfs path2fid $DIR/$tdir/f)
24803         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24804         # rmfid should fail
24805         cnt=$(ls -1 $DIR/$tdir | wc -l)
24806         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24807
24808         chmod a+rw $DIR/$tdir
24809         ls -la $DIR/$tdir
24810         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24811         # rmfid should fail
24812         cnt=$(ls -1 $DIR/$tdir | wc -l)
24813         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24814
24815         rm -f $DIR/$tdir/f
24816         $RUNAS touch $DIR/$tdir/f
24817         FID=$(lfs path2fid $DIR/$tdir/f)
24818         echo "rmfid as root"
24819         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24820         cnt=$(ls -1 $DIR/$tdir | wc -l)
24821         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24822
24823         rm -f $DIR/$tdir/f
24824         $RUNAS touch $DIR/$tdir/f
24825         cnt=$(ls -1 $DIR/$tdir | wc -l)
24826         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24827         FID=$(lfs path2fid $DIR/$tdir/f)
24828         # rmfid w/o user_fid2path mount option should fail
24829         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24830         cnt=$(ls -1 $DIR/$tdir | wc -l)
24831         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24832
24833         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24834         stack_trap "rmdir $tmpdir"
24835         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24836                 error "failed to mount client'"
24837         stack_trap "umount_client $tmpdir"
24838
24839         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24840         # rmfid should succeed
24841         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24842         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24843
24844         # rmfid shouldn't allow to remove files due to dir's permission
24845         chmod a+rwx $tmpdir/$tdir
24846         touch $tmpdir/$tdir/f
24847         ls -la $tmpdir/$tdir
24848         FID=$(lfs path2fid $tmpdir/$tdir/f)
24849         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24850         return 0
24851 }
24852 run_test 421f "rmfid checks permissions"
24853
24854 test_421g() {
24855         local cnt
24856         local FIDS
24857
24858         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24859         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24860                 skip "Need MDS version at least 2.12.54"
24861
24862         mkdir -p $DIR/$tdir
24863         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24864         createmany -o $DIR/$tdir/striped_dir/f 512
24865         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24866         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24867
24868         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24869                 sed "s/[/][^:]*://g")
24870
24871         rm -f $DIR/$tdir/striped_dir/f1*
24872         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24873         removed=$((512 - cnt))
24874
24875         # few files have been just removed, so we expect
24876         # rmfid to fail on their fids
24877         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24878         [ $removed != $errors ] && error "$errors != $removed"
24879
24880         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24881         rm -rf $DIR/$tdir
24882         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24883 }
24884 run_test 421g "rmfid to return errors properly"
24885
24886 test_422() {
24887         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24888         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24889         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24890         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24891         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24892
24893         local amc=$(at_max_get client)
24894         local amo=$(at_max_get mds1)
24895         local timeout=`lctl get_param -n timeout`
24896
24897         at_max_set 0 client
24898         at_max_set 0 mds1
24899
24900 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24901         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24902                         fail_val=$(((2*timeout + 10)*1000))
24903         touch $DIR/$tdir/d3/file &
24904         sleep 2
24905 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24906         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24907                         fail_val=$((2*timeout + 5))
24908         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24909         local pid=$!
24910         sleep 1
24911         kill -9 $pid
24912         sleep $((2 * timeout))
24913         echo kill $pid
24914         kill -9 $pid
24915         lctl mark touch
24916         touch $DIR/$tdir/d2/file3
24917         touch $DIR/$tdir/d2/file4
24918         touch $DIR/$tdir/d2/file5
24919
24920         wait
24921         at_max_set $amc client
24922         at_max_set $amo mds1
24923
24924         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24925         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24926                 error "Watchdog is always throttled"
24927 }
24928 run_test 422 "kill a process with RPC in progress"
24929
24930 stat_test() {
24931     df -h $MOUNT &
24932     df -h $MOUNT &
24933     df -h $MOUNT &
24934     df -h $MOUNT &
24935     df -h $MOUNT &
24936     df -h $MOUNT &
24937 }
24938
24939 test_423() {
24940     local _stats
24941     # ensure statfs cache is expired
24942     sleep 2;
24943
24944     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24945     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24946
24947     return 0
24948 }
24949 run_test 423 "statfs should return a right data"
24950
24951 test_424() {
24952 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24953         $LCTL set_param fail_loc=0x80000522
24954         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24955         rm -f $DIR/$tfile
24956 }
24957 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24958
24959 test_425() {
24960         test_mkdir -c -1 $DIR/$tdir
24961         $LFS setstripe -c -1 $DIR/$tdir
24962
24963         lru_resize_disable "" 100
24964         stack_trap "lru_resize_enable" EXIT
24965
24966         sleep 5
24967
24968         for i in $(seq $((MDSCOUNT * 125))); do
24969                 local t=$DIR/$tdir/$tfile_$i
24970
24971                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24972                         error_noexit "Create file $t"
24973         done
24974         stack_trap "rm -rf $DIR/$tdir" EXIT
24975
24976         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24977                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24978                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24979
24980                 [ $lock_count -le $lru_size ] ||
24981                         error "osc lock count $lock_count > lru size $lru_size"
24982         done
24983
24984         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24985                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24986                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24987
24988                 [ $lock_count -le $lru_size ] ||
24989                         error "mdc lock count $lock_count > lru size $lru_size"
24990         done
24991 }
24992 run_test 425 "lock count should not exceed lru size"
24993
24994 test_426() {
24995         splice-test -r $DIR/$tfile
24996         splice-test -rd $DIR/$tfile
24997         splice-test $DIR/$tfile
24998         splice-test -d $DIR/$tfile
24999 }
25000 run_test 426 "splice test on Lustre"
25001
25002 test_427() {
25003         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25004         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25005                 skip "Need MDS version at least 2.12.4"
25006         local log
25007
25008         mkdir $DIR/$tdir
25009         mkdir $DIR/$tdir/1
25010         mkdir $DIR/$tdir/2
25011         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25012         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25013
25014         $LFS getdirstripe $DIR/$tdir/1/dir
25015
25016         #first setfattr for creating updatelog
25017         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25018
25019 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25020         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25021         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25022         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25023
25024         sleep 2
25025         fail mds2
25026         wait_recovery_complete mds2 $((2*TIMEOUT))
25027
25028         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25029         echo $log | grep "get update log failed" &&
25030                 error "update log corruption is detected" || true
25031 }
25032 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25033
25034 test_428() {
25035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25036         local cache_limit=$CACHE_MAX
25037
25038         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25039         $LCTL set_param -n llite.*.max_cached_mb=64
25040
25041         mkdir $DIR/$tdir
25042         $LFS setstripe -c 1 $DIR/$tdir
25043         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25044         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25045         #test write
25046         for f in $(seq 4); do
25047                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25048         done
25049         wait
25050
25051         cancel_lru_locks osc
25052         # Test read
25053         for f in $(seq 4); do
25054                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25055         done
25056         wait
25057 }
25058 run_test 428 "large block size IO should not hang"
25059
25060 test_429() { # LU-7915 / LU-10948
25061         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25062         local testfile=$DIR/$tfile
25063         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25064         local new_flag=1
25065         local first_rpc
25066         local second_rpc
25067         local third_rpc
25068
25069         $LCTL get_param $ll_opencache_threshold_count ||
25070                 skip "client does not have opencache parameter"
25071
25072         set_opencache $new_flag
25073         stack_trap "restore_opencache"
25074         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25075                 error "enable opencache failed"
25076         touch $testfile
25077         # drop MDC DLM locks
25078         cancel_lru_locks mdc
25079         # clear MDC RPC stats counters
25080         $LCTL set_param $mdc_rpcstats=clear
25081
25082         # According to the current implementation, we need to run 3 times
25083         # open & close file to verify if opencache is enabled correctly.
25084         # 1st, RPCs are sent for lookup/open and open handle is released on
25085         #      close finally.
25086         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25087         #      so open handle won't be released thereafter.
25088         # 3rd, No RPC is sent out.
25089         $MULTIOP $testfile oc || error "multiop failed"
25090         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25091         echo "1st: $first_rpc RPCs in flight"
25092
25093         $MULTIOP $testfile oc || error "multiop failed"
25094         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25095         echo "2nd: $second_rpc RPCs in flight"
25096
25097         $MULTIOP $testfile oc || error "multiop failed"
25098         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25099         echo "3rd: $third_rpc RPCs in flight"
25100
25101         #verify no MDC RPC is sent
25102         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25103 }
25104 run_test 429 "verify if opencache flag on client side does work"
25105
25106 lseek_test_430() {
25107         local offset
25108         local file=$1
25109
25110         # data at [200K, 400K)
25111         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25112                 error "256K->512K dd fails"
25113         # data at [2M, 3M)
25114         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25115                 error "2M->3M dd fails"
25116         # data at [4M, 5M)
25117         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25118                 error "4M->5M dd fails"
25119         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25120         # start at first component hole #1
25121         printf "Seeking hole from 1000 ... "
25122         offset=$(lseek_test -l 1000 $file)
25123         echo $offset
25124         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25125         printf "Seeking data from 1000 ... "
25126         offset=$(lseek_test -d 1000 $file)
25127         echo $offset
25128         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25129
25130         # start at first component data block
25131         printf "Seeking hole from 300000 ... "
25132         offset=$(lseek_test -l 300000 $file)
25133         echo $offset
25134         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25135         printf "Seeking data from 300000 ... "
25136         offset=$(lseek_test -d 300000 $file)
25137         echo $offset
25138         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25139
25140         # start at the first component but beyond end of object size
25141         printf "Seeking hole from 1000000 ... "
25142         offset=$(lseek_test -l 1000000 $file)
25143         echo $offset
25144         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25145         printf "Seeking data from 1000000 ... "
25146         offset=$(lseek_test -d 1000000 $file)
25147         echo $offset
25148         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25149
25150         # start at second component stripe 2 (empty file)
25151         printf "Seeking hole from 1500000 ... "
25152         offset=$(lseek_test -l 1500000 $file)
25153         echo $offset
25154         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25155         printf "Seeking data from 1500000 ... "
25156         offset=$(lseek_test -d 1500000 $file)
25157         echo $offset
25158         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25159
25160         # start at second component stripe 1 (all data)
25161         printf "Seeking hole from 3000000 ... "
25162         offset=$(lseek_test -l 3000000 $file)
25163         echo $offset
25164         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25165         printf "Seeking data from 3000000 ... "
25166         offset=$(lseek_test -d 3000000 $file)
25167         echo $offset
25168         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25169
25170         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25171                 error "2nd dd fails"
25172         echo "Add data block at 640K...1280K"
25173
25174         # start at before new data block, in hole
25175         printf "Seeking hole from 600000 ... "
25176         offset=$(lseek_test -l 600000 $file)
25177         echo $offset
25178         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25179         printf "Seeking data from 600000 ... "
25180         offset=$(lseek_test -d 600000 $file)
25181         echo $offset
25182         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25183
25184         # start at the first component new data block
25185         printf "Seeking hole from 1000000 ... "
25186         offset=$(lseek_test -l 1000000 $file)
25187         echo $offset
25188         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25189         printf "Seeking data from 1000000 ... "
25190         offset=$(lseek_test -d 1000000 $file)
25191         echo $offset
25192         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25193
25194         # start at second component stripe 2, new data
25195         printf "Seeking hole from 1200000 ... "
25196         offset=$(lseek_test -l 1200000 $file)
25197         echo $offset
25198         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25199         printf "Seeking data from 1200000 ... "
25200         offset=$(lseek_test -d 1200000 $file)
25201         echo $offset
25202         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25203
25204         # start beyond file end
25205         printf "Using offset > filesize ... "
25206         lseek_test -l 4000000 $file && error "lseek should fail"
25207         printf "Using offset > filesize ... "
25208         lseek_test -d 4000000 $file && error "lseek should fail"
25209
25210         printf "Done\n\n"
25211 }
25212
25213 test_430a() {
25214         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25215                 skip "MDT does not support SEEK_HOLE"
25216
25217         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25218                 skip "OST does not support SEEK_HOLE"
25219
25220         local file=$DIR/$tdir/$tfile
25221
25222         mkdir -p $DIR/$tdir
25223
25224         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25225         # OST stripe #1 will have continuous data at [1M, 3M)
25226         # OST stripe #2 is empty
25227         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25228         lseek_test_430 $file
25229         rm $file
25230         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25231         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25232         lseek_test_430 $file
25233         rm $file
25234         $LFS setstripe -c2 -S 512K $file
25235         echo "Two stripes, stripe size 512K"
25236         lseek_test_430 $file
25237         rm $file
25238         # FLR with stale mirror
25239         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25240                        -N -c2 -S 1M $file
25241         echo "Mirrored file:"
25242         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25243         echo "Plain 2 stripes 1M"
25244         lseek_test_430 $file
25245         rm $file
25246 }
25247 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25248
25249 test_430b() {
25250         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25251                 skip "OST does not support SEEK_HOLE"
25252
25253         local offset
25254         local file=$DIR/$tdir/$tfile
25255
25256         mkdir -p $DIR/$tdir
25257         # Empty layout lseek should fail
25258         $MCREATE $file
25259         # seek from 0
25260         printf "Seeking hole from 0 ... "
25261         lseek_test -l 0 $file && error "lseek should fail"
25262         printf "Seeking data from 0 ... "
25263         lseek_test -d 0 $file && error "lseek should fail"
25264         rm $file
25265
25266         # 1M-hole file
25267         $LFS setstripe -E 1M -c2 -E eof $file
25268         $TRUNCATE $file 1048576
25269         printf "Seeking hole from 1000000 ... "
25270         offset=$(lseek_test -l 1000000 $file)
25271         echo $offset
25272         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25273         printf "Seeking data from 1000000 ... "
25274         lseek_test -d 1000000 $file && error "lseek should fail"
25275         rm $file
25276
25277         # full component followed by non-inited one
25278         $LFS setstripe -E 1M -c2 -E eof $file
25279         dd if=/dev/urandom of=$file bs=1M count=1
25280         printf "Seeking hole from 1000000 ... "
25281         offset=$(lseek_test -l 1000000 $file)
25282         echo $offset
25283         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25284         printf "Seeking hole from 1048576 ... "
25285         lseek_test -l 1048576 $file && error "lseek should fail"
25286         # init second component and truncate back
25287         echo "123" >> $file
25288         $TRUNCATE $file 1048576
25289         printf "Seeking hole from 1000000 ... "
25290         offset=$(lseek_test -l 1000000 $file)
25291         echo $offset
25292         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25293         printf "Seeking hole from 1048576 ... "
25294         lseek_test -l 1048576 $file && error "lseek should fail"
25295         # boundary checks for big values
25296         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25297         offset=$(lseek_test -d 0 $file.10g)
25298         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25299         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25300         offset=$(lseek_test -d 0 $file.100g)
25301         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25302         return 0
25303 }
25304 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25305
25306 test_430c() {
25307         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25308                 skip "OST does not support SEEK_HOLE"
25309
25310         local file=$DIR/$tdir/$tfile
25311         local start
25312
25313         mkdir -p $DIR/$tdir
25314         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25315
25316         # cp version 8.33+ prefers lseek over fiemap
25317         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25318                 start=$SECONDS
25319                 time cp $file /dev/null
25320                 (( SECONDS - start < 5 )) ||
25321                         error "cp: too long runtime $((SECONDS - start))"
25322
25323         fi
25324         # tar version 1.29+ supports SEEK_HOLE/DATA
25325         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25326                 start=$SECONDS
25327                 time tar cS $file - | cat > /dev/null
25328                 (( SECONDS - start < 5 )) ||
25329                         error "tar: too long runtime $((SECONDS - start))"
25330         fi
25331 }
25332 run_test 430c "lseek: external tools check"
25333
25334 test_431() { # LU-14187
25335         local file=$DIR/$tdir/$tfile
25336
25337         mkdir -p $DIR/$tdir
25338         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25339         dd if=/dev/urandom of=$file bs=4k count=1
25340         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25341         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25342         #define OBD_FAIL_OST_RESTART_IO 0x251
25343         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25344         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25345         cp $file $file.0
25346         cancel_lru_locks
25347         sync_all_data
25348         echo 3 > /proc/sys/vm/drop_caches
25349         diff  $file $file.0 || error "data diff"
25350 }
25351 run_test 431 "Restart transaction for IO"
25352
25353 prep_801() {
25354         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25355         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25356                 skip "Need server version at least 2.9.55"
25357
25358         start_full_debug_logging
25359 }
25360
25361 post_801() {
25362         stop_full_debug_logging
25363 }
25364
25365 barrier_stat() {
25366         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25367                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25368                            awk '/The barrier for/ { print $7 }')
25369                 echo $st
25370         else
25371                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25372                 echo \'$st\'
25373         fi
25374 }
25375
25376 barrier_expired() {
25377         local expired
25378
25379         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25380                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25381                           awk '/will be expired/ { print $7 }')
25382         else
25383                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25384         fi
25385
25386         echo $expired
25387 }
25388
25389 test_801a() {
25390         prep_801
25391
25392         echo "Start barrier_freeze at: $(date)"
25393         #define OBD_FAIL_BARRIER_DELAY          0x2202
25394         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25395         # Do not reduce barrier time - See LU-11873
25396         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25397
25398         sleep 2
25399         local b_status=$(barrier_stat)
25400         echo "Got barrier status at: $(date)"
25401         [ "$b_status" = "'freezing_p1'" ] ||
25402                 error "(1) unexpected barrier status $b_status"
25403
25404         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25405         wait
25406         b_status=$(barrier_stat)
25407         [ "$b_status" = "'frozen'" ] ||
25408                 error "(2) unexpected barrier status $b_status"
25409
25410         local expired=$(barrier_expired)
25411         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25412         sleep $((expired + 3))
25413
25414         b_status=$(barrier_stat)
25415         [ "$b_status" = "'expired'" ] ||
25416                 error "(3) unexpected barrier status $b_status"
25417
25418         # Do not reduce barrier time - See LU-11873
25419         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25420                 error "(4) fail to freeze barrier"
25421
25422         b_status=$(barrier_stat)
25423         [ "$b_status" = "'frozen'" ] ||
25424                 error "(5) unexpected barrier status $b_status"
25425
25426         echo "Start barrier_thaw at: $(date)"
25427         #define OBD_FAIL_BARRIER_DELAY          0x2202
25428         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25429         do_facet mgs $LCTL barrier_thaw $FSNAME &
25430
25431         sleep 2
25432         b_status=$(barrier_stat)
25433         echo "Got barrier status at: $(date)"
25434         [ "$b_status" = "'thawing'" ] ||
25435                 error "(6) unexpected barrier status $b_status"
25436
25437         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25438         wait
25439         b_status=$(barrier_stat)
25440         [ "$b_status" = "'thawed'" ] ||
25441                 error "(7) unexpected barrier status $b_status"
25442
25443         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25444         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25445         do_facet mgs $LCTL barrier_freeze $FSNAME
25446
25447         b_status=$(barrier_stat)
25448         [ "$b_status" = "'failed'" ] ||
25449                 error "(8) unexpected barrier status $b_status"
25450
25451         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25452         do_facet mgs $LCTL barrier_thaw $FSNAME
25453
25454         post_801
25455 }
25456 run_test 801a "write barrier user interfaces and stat machine"
25457
25458 test_801b() {
25459         prep_801
25460
25461         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25462         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25463         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25464         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25465         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25466
25467         cancel_lru_locks mdc
25468
25469         # 180 seconds should be long enough
25470         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25471
25472         local b_status=$(barrier_stat)
25473         [ "$b_status" = "'frozen'" ] ||
25474                 error "(6) unexpected barrier status $b_status"
25475
25476         mkdir $DIR/$tdir/d0/d10 &
25477         mkdir_pid=$!
25478
25479         touch $DIR/$tdir/d1/f13 &
25480         touch_pid=$!
25481
25482         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25483         ln_pid=$!
25484
25485         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25486         mv_pid=$!
25487
25488         rm -f $DIR/$tdir/d4/f12 &
25489         rm_pid=$!
25490
25491         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25492
25493         # To guarantee taht the 'stat' is not blocked
25494         b_status=$(barrier_stat)
25495         [ "$b_status" = "'frozen'" ] ||
25496                 error "(8) unexpected barrier status $b_status"
25497
25498         # let above commands to run at background
25499         sleep 5
25500
25501         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25502         ps -p $touch_pid || error "(10) touch should be blocked"
25503         ps -p $ln_pid || error "(11) link should be blocked"
25504         ps -p $mv_pid || error "(12) rename should be blocked"
25505         ps -p $rm_pid || error "(13) unlink should be blocked"
25506
25507         b_status=$(barrier_stat)
25508         [ "$b_status" = "'frozen'" ] ||
25509                 error "(14) unexpected barrier status $b_status"
25510
25511         do_facet mgs $LCTL barrier_thaw $FSNAME
25512         b_status=$(barrier_stat)
25513         [ "$b_status" = "'thawed'" ] ||
25514                 error "(15) unexpected barrier status $b_status"
25515
25516         wait $mkdir_pid || error "(16) mkdir should succeed"
25517         wait $touch_pid || error "(17) touch should succeed"
25518         wait $ln_pid || error "(18) link should succeed"
25519         wait $mv_pid || error "(19) rename should succeed"
25520         wait $rm_pid || error "(20) unlink should succeed"
25521
25522         post_801
25523 }
25524 run_test 801b "modification will be blocked by write barrier"
25525
25526 test_801c() {
25527         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25528
25529         prep_801
25530
25531         stop mds2 || error "(1) Fail to stop mds2"
25532
25533         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25534
25535         local b_status=$(barrier_stat)
25536         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25537                 do_facet mgs $LCTL barrier_thaw $FSNAME
25538                 error "(2) unexpected barrier status $b_status"
25539         }
25540
25541         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25542                 error "(3) Fail to rescan barrier bitmap"
25543
25544         # Do not reduce barrier time - See LU-11873
25545         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25546
25547         b_status=$(barrier_stat)
25548         [ "$b_status" = "'frozen'" ] ||
25549                 error "(4) unexpected barrier status $b_status"
25550
25551         do_facet mgs $LCTL barrier_thaw $FSNAME
25552         b_status=$(barrier_stat)
25553         [ "$b_status" = "'thawed'" ] ||
25554                 error "(5) unexpected barrier status $b_status"
25555
25556         local devname=$(mdsdevname 2)
25557
25558         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25559
25560         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25561                 error "(7) Fail to rescan barrier bitmap"
25562
25563         post_801
25564 }
25565 run_test 801c "rescan barrier bitmap"
25566
25567 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25568 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25569 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25570 saved_MOUNT_OPTS=$MOUNT_OPTS
25571
25572 cleanup_802a() {
25573         trap 0
25574
25575         stopall
25576         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25577         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25578         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25579         MOUNT_OPTS=$saved_MOUNT_OPTS
25580         setupall
25581 }
25582
25583 test_802a() {
25584         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25585         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25586         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25587                 skip "Need server version at least 2.9.55"
25588
25589         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25590
25591         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25592
25593         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25594                 error "(2) Fail to copy"
25595
25596         trap cleanup_802a EXIT
25597
25598         # sync by force before remount as readonly
25599         sync; sync_all_data; sleep 3; sync_all_data
25600
25601         stopall
25602
25603         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25604         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25605         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25606
25607         echo "Mount the server as read only"
25608         setupall server_only || error "(3) Fail to start servers"
25609
25610         echo "Mount client without ro should fail"
25611         mount_client $MOUNT &&
25612                 error "(4) Mount client without 'ro' should fail"
25613
25614         echo "Mount client with ro should succeed"
25615         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25616         mount_client $MOUNT ||
25617                 error "(5) Mount client with 'ro' should succeed"
25618
25619         echo "Modify should be refused"
25620         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25621
25622         echo "Read should be allowed"
25623         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25624                 error "(7) Read should succeed under ro mode"
25625
25626         cleanup_802a
25627 }
25628 run_test 802a "simulate readonly device"
25629
25630 test_802b() {
25631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25632         remote_mds_nodsh && skip "remote MDS with nodsh"
25633
25634         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25635                 skip "readonly option not available"
25636
25637         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25638
25639         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25640                 error "(2) Fail to copy"
25641
25642         # write back all cached data before setting MDT to readonly
25643         cancel_lru_locks
25644         sync_all_data
25645
25646         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25647         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25648
25649         echo "Modify should be refused"
25650         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25651
25652         echo "Read should be allowed"
25653         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25654                 error "(7) Read should succeed under ro mode"
25655
25656         # disable readonly
25657         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25658 }
25659 run_test 802b "be able to set MDTs to readonly"
25660
25661 test_803a() {
25662         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25663         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25664                 skip "MDS needs to be newer than 2.10.54"
25665
25666         mkdir_on_mdt0 $DIR/$tdir
25667         # Create some objects on all MDTs to trigger related logs objects
25668         for idx in $(seq $MDSCOUNT); do
25669                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25670                         $DIR/$tdir/dir${idx} ||
25671                         error "Fail to create $DIR/$tdir/dir${idx}"
25672         done
25673
25674         sync; sleep 3
25675         wait_delete_completed # ensure old test cleanups are finished
25676         echo "before create:"
25677         $LFS df -i $MOUNT
25678         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25679
25680         for i in {1..10}; do
25681                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25682                         error "Fail to create $DIR/$tdir/foo$i"
25683         done
25684
25685         sync; sleep 3
25686         echo "after create:"
25687         $LFS df -i $MOUNT
25688         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25689
25690         # allow for an llog to be cleaned up during the test
25691         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25692                 error "before ($before_used) + 10 > after ($after_used)"
25693
25694         for i in {1..10}; do
25695                 rm -rf $DIR/$tdir/foo$i ||
25696                         error "Fail to remove $DIR/$tdir/foo$i"
25697         done
25698
25699         sleep 3 # avoid MDT return cached statfs
25700         wait_delete_completed
25701         echo "after unlink:"
25702         $LFS df -i $MOUNT
25703         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25704
25705         # allow for an llog to be created during the test
25706         [ $after_used -le $((before_used + 1)) ] ||
25707                 error "after ($after_used) > before ($before_used) + 1"
25708 }
25709 run_test 803a "verify agent object for remote object"
25710
25711 test_803b() {
25712         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25713         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25714                 skip "MDS needs to be newer than 2.13.56"
25715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25716
25717         for i in $(seq 0 $((MDSCOUNT - 1))); do
25718                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25719         done
25720
25721         local before=0
25722         local after=0
25723
25724         local tmp
25725
25726         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25727         for i in $(seq 0 $((MDSCOUNT - 1))); do
25728                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25729                         awk '/getattr/ { print $2 }')
25730                 before=$((before + tmp))
25731         done
25732         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25733         for i in $(seq 0 $((MDSCOUNT - 1))); do
25734                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25735                         awk '/getattr/ { print $2 }')
25736                 after=$((after + tmp))
25737         done
25738
25739         [ $before -eq $after ] || error "getattr count $before != $after"
25740 }
25741 run_test 803b "remote object can getattr from cache"
25742
25743 test_804() {
25744         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25745         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25746                 skip "MDS needs to be newer than 2.10.54"
25747         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25748
25749         mkdir -p $DIR/$tdir
25750         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25751                 error "Fail to create $DIR/$tdir/dir0"
25752
25753         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25754         local dev=$(mdsdevname 2)
25755
25756         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25757                 grep ${fid} || error "NOT found agent entry for dir0"
25758
25759         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25760                 error "Fail to create $DIR/$tdir/dir1"
25761
25762         touch $DIR/$tdir/dir1/foo0 ||
25763                 error "Fail to create $DIR/$tdir/dir1/foo0"
25764         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25765         local rc=0
25766
25767         for idx in $(seq $MDSCOUNT); do
25768                 dev=$(mdsdevname $idx)
25769                 do_facet mds${idx} \
25770                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25771                         grep ${fid} && rc=$idx
25772         done
25773
25774         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25775                 error "Fail to rename foo0 to foo1"
25776         if [ $rc -eq 0 ]; then
25777                 for idx in $(seq $MDSCOUNT); do
25778                         dev=$(mdsdevname $idx)
25779                         do_facet mds${idx} \
25780                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25781                         grep ${fid} && rc=$idx
25782                 done
25783         fi
25784
25785         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25786                 error "Fail to rename foo1 to foo2"
25787         if [ $rc -eq 0 ]; then
25788                 for idx in $(seq $MDSCOUNT); do
25789                         dev=$(mdsdevname $idx)
25790                         do_facet mds${idx} \
25791                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25792                         grep ${fid} && rc=$idx
25793                 done
25794         fi
25795
25796         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25797
25798         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25799                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25800         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25801                 error "Fail to rename foo2 to foo0"
25802         unlink $DIR/$tdir/dir1/foo0 ||
25803                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25804         rm -rf $DIR/$tdir/dir0 ||
25805                 error "Fail to rm $DIR/$tdir/dir0"
25806
25807         for idx in $(seq $MDSCOUNT); do
25808                 dev=$(mdsdevname $idx)
25809                 rc=0
25810
25811                 stop mds${idx}
25812                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25813                         rc=$?
25814                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25815                         error "mount mds$idx failed"
25816                 df $MOUNT > /dev/null 2>&1
25817
25818                 # e2fsck should not return error
25819                 [ $rc -eq 0 ] ||
25820                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25821         done
25822 }
25823 run_test 804 "verify agent entry for remote entry"
25824
25825 cleanup_805() {
25826         do_facet $SINGLEMDS zfs set quota=$old $fsset
25827         unlinkmany $DIR/$tdir/f- 1000000
25828         trap 0
25829 }
25830
25831 test_805() {
25832         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25833         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25834         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25835                 skip "netfree not implemented before 0.7"
25836         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25837                 skip "Need MDS version at least 2.10.57"
25838
25839         local fsset
25840         local freekb
25841         local usedkb
25842         local old
25843         local quota
25844         local pref="osd-zfs.$FSNAME-MDT0000."
25845
25846         # limit available space on MDS dataset to meet nospace issue
25847         # quickly. then ZFS 0.7.2 can use reserved space if asked
25848         # properly (using netfree flag in osd_declare_destroy()
25849         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25850         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25851                 gawk '{print $3}')
25852         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25853         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25854         let "usedkb=usedkb-freekb"
25855         let "freekb=freekb/2"
25856         if let "freekb > 5000"; then
25857                 let "freekb=5000"
25858         fi
25859         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25860         trap cleanup_805 EXIT
25861         mkdir_on_mdt0 $DIR/$tdir
25862         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25863                 error "Can't set PFL layout"
25864         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25865         rm -rf $DIR/$tdir || error "not able to remove"
25866         do_facet $SINGLEMDS zfs set quota=$old $fsset
25867         trap 0
25868 }
25869 run_test 805 "ZFS can remove from full fs"
25870
25871 # Size-on-MDS test
25872 check_lsom_data()
25873 {
25874         local file=$1
25875         local expect=$(stat -c %s $file)
25876
25877         check_lsom_size $1 $expect
25878
25879         local blocks=$($LFS getsom -b $file)
25880         expect=$(stat -c %b $file)
25881         [[ $blocks == $expect ]] ||
25882                 error "$file expected blocks: $expect, got: $blocks"
25883 }
25884
25885 check_lsom_size()
25886 {
25887         local size
25888         local expect=$2
25889
25890         cancel_lru_locks mdc
25891
25892         size=$($LFS getsom -s $1)
25893         [[ $size == $expect ]] ||
25894                 error "$file expected size: $expect, got: $size"
25895 }
25896
25897 test_806() {
25898         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25899                 skip "Need MDS version at least 2.11.52"
25900
25901         local bs=1048576
25902
25903         touch $DIR/$tfile || error "touch $tfile failed"
25904
25905         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25906         save_lustre_params client "llite.*.xattr_cache" > $save
25907         lctl set_param llite.*.xattr_cache=0
25908         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25909
25910         # single-threaded write
25911         echo "Test SOM for single-threaded write"
25912         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25913                 error "write $tfile failed"
25914         check_lsom_size $DIR/$tfile $bs
25915
25916         local num=32
25917         local size=$(($num * $bs))
25918         local offset=0
25919         local i
25920
25921         echo "Test SOM for single client multi-threaded($num) write"
25922         $TRUNCATE $DIR/$tfile 0
25923         for ((i = 0; i < $num; i++)); do
25924                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25925                 local pids[$i]=$!
25926                 offset=$((offset + $bs))
25927         done
25928         for (( i=0; i < $num; i++ )); do
25929                 wait ${pids[$i]}
25930         done
25931         check_lsom_size $DIR/$tfile $size
25932
25933         $TRUNCATE $DIR/$tfile 0
25934         for ((i = 0; i < $num; i++)); do
25935                 offset=$((offset - $bs))
25936                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25937                 local pids[$i]=$!
25938         done
25939         for (( i=0; i < $num; i++ )); do
25940                 wait ${pids[$i]}
25941         done
25942         check_lsom_size $DIR/$tfile $size
25943
25944         # multi-client writes
25945         num=$(get_node_count ${CLIENTS//,/ })
25946         size=$(($num * $bs))
25947         offset=0
25948         i=0
25949
25950         echo "Test SOM for multi-client ($num) writes"
25951         $TRUNCATE $DIR/$tfile 0
25952         for client in ${CLIENTS//,/ }; do
25953                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25954                 local pids[$i]=$!
25955                 i=$((i + 1))
25956                 offset=$((offset + $bs))
25957         done
25958         for (( i=0; i < $num; i++ )); do
25959                 wait ${pids[$i]}
25960         done
25961         check_lsom_size $DIR/$tfile $offset
25962
25963         i=0
25964         $TRUNCATE $DIR/$tfile 0
25965         for client in ${CLIENTS//,/ }; do
25966                 offset=$((offset - $bs))
25967                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25968                 local pids[$i]=$!
25969                 i=$((i + 1))
25970         done
25971         for (( i=0; i < $num; i++ )); do
25972                 wait ${pids[$i]}
25973         done
25974         check_lsom_size $DIR/$tfile $size
25975
25976         # verify truncate
25977         echo "Test SOM for truncate"
25978         $TRUNCATE $DIR/$tfile 1048576
25979         check_lsom_size $DIR/$tfile 1048576
25980         $TRUNCATE $DIR/$tfile 1234
25981         check_lsom_size $DIR/$tfile 1234
25982
25983         # verify SOM blocks count
25984         echo "Verify SOM block count"
25985         $TRUNCATE $DIR/$tfile 0
25986         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25987                 error "failed to write file $tfile"
25988         check_lsom_data $DIR/$tfile
25989 }
25990 run_test 806 "Verify Lazy Size on MDS"
25991
25992 test_807() {
25993         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25994         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25995                 skip "Need MDS version at least 2.11.52"
25996
25997         # Registration step
25998         changelog_register || error "changelog_register failed"
25999         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26000         changelog_users $SINGLEMDS | grep -q $cl_user ||
26001                 error "User $cl_user not found in changelog_users"
26002
26003         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26004         save_lustre_params client "llite.*.xattr_cache" > $save
26005         lctl set_param llite.*.xattr_cache=0
26006         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26007
26008         rm -rf $DIR/$tdir || error "rm $tdir failed"
26009         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26010         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26011         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26012         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26013                 error "truncate $tdir/trunc failed"
26014
26015         local bs=1048576
26016         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26017                 error "write $tfile failed"
26018
26019         # multi-client wirtes
26020         local num=$(get_node_count ${CLIENTS//,/ })
26021         local offset=0
26022         local i=0
26023
26024         echo "Test SOM for multi-client ($num) writes"
26025         touch $DIR/$tfile || error "touch $tfile failed"
26026         $TRUNCATE $DIR/$tfile 0
26027         for client in ${CLIENTS//,/ }; do
26028                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26029                 local pids[$i]=$!
26030                 i=$((i + 1))
26031                 offset=$((offset + $bs))
26032         done
26033         for (( i=0; i < $num; i++ )); do
26034                 wait ${pids[$i]}
26035         done
26036
26037         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26038         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26039         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26040         check_lsom_data $DIR/$tdir/trunc
26041         check_lsom_data $DIR/$tdir/single_dd
26042         check_lsom_data $DIR/$tfile
26043
26044         rm -rf $DIR/$tdir
26045         # Deregistration step
26046         changelog_deregister || error "changelog_deregister failed"
26047 }
26048 run_test 807 "verify LSOM syncing tool"
26049
26050 check_som_nologged()
26051 {
26052         local lines=$($LFS changelog $FSNAME-MDT0000 |
26053                 grep 'x=trusted.som' | wc -l)
26054         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26055 }
26056
26057 test_808() {
26058         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26059                 skip "Need MDS version at least 2.11.55"
26060
26061         # Registration step
26062         changelog_register || error "changelog_register failed"
26063
26064         touch $DIR/$tfile || error "touch $tfile failed"
26065         check_som_nologged
26066
26067         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26068                 error "write $tfile failed"
26069         check_som_nologged
26070
26071         $TRUNCATE $DIR/$tfile 1234
26072         check_som_nologged
26073
26074         $TRUNCATE $DIR/$tfile 1048576
26075         check_som_nologged
26076
26077         # Deregistration step
26078         changelog_deregister || error "changelog_deregister failed"
26079 }
26080 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26081
26082 check_som_nodata()
26083 {
26084         $LFS getsom $1
26085         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26086 }
26087
26088 test_809() {
26089         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26090                 skip "Need MDS version at least 2.11.56"
26091
26092         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26093                 error "failed to create DoM-only file $DIR/$tfile"
26094         touch $DIR/$tfile || error "touch $tfile failed"
26095         check_som_nodata $DIR/$tfile
26096
26097         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26098                 error "write $tfile failed"
26099         check_som_nodata $DIR/$tfile
26100
26101         $TRUNCATE $DIR/$tfile 1234
26102         check_som_nodata $DIR/$tfile
26103
26104         $TRUNCATE $DIR/$tfile 4097
26105         check_som_nodata $DIR/$file
26106 }
26107 run_test 809 "Verify no SOM xattr store for DoM-only files"
26108
26109 test_810() {
26110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26111         $GSS && skip_env "could not run with gss"
26112         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26113                 skip "OST < 2.12.58 doesn't align checksum"
26114
26115         set_checksums 1
26116         stack_trap "set_checksums $ORIG_CSUM" EXIT
26117         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26118
26119         local csum
26120         local before
26121         local after
26122         for csum in $CKSUM_TYPES; do
26123                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26124                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26125                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26126                         eval set -- $i
26127                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26128                         before=$(md5sum $DIR/$tfile)
26129                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26130                         after=$(md5sum $DIR/$tfile)
26131                         [ "$before" == "$after" ] ||
26132                                 error "$csum: $before != $after bs=$1 seek=$2"
26133                 done
26134         done
26135 }
26136 run_test 810 "partial page writes on ZFS (LU-11663)"
26137
26138 test_812a() {
26139         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26140                 skip "OST < 2.12.51 doesn't support this fail_loc"
26141
26142         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26143         # ensure ost1 is connected
26144         stat $DIR/$tfile >/dev/null || error "can't stat"
26145         wait_osc_import_state client ost1 FULL
26146         # no locks, no reqs to let the connection idle
26147         cancel_lru_locks osc
26148
26149         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26150 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26151         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26152         wait_osc_import_state client ost1 CONNECTING
26153         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26154
26155         stat $DIR/$tfile >/dev/null || error "can't stat file"
26156 }
26157 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26158
26159 test_812b() { # LU-12378
26160         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26161                 skip "OST < 2.12.51 doesn't support this fail_loc"
26162
26163         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26164         # ensure ost1 is connected
26165         stat $DIR/$tfile >/dev/null || error "can't stat"
26166         wait_osc_import_state client ost1 FULL
26167         # no locks, no reqs to let the connection idle
26168         cancel_lru_locks osc
26169
26170         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26171 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26172         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26173         wait_osc_import_state client ost1 CONNECTING
26174         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26175
26176         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26177         wait_osc_import_state client ost1 IDLE
26178 }
26179 run_test 812b "do not drop no resend request for idle connect"
26180
26181 test_812c() {
26182         local old
26183
26184         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26185
26186         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26187         $LFS getstripe $DIR/$tfile
26188         $LCTL set_param osc.*.idle_timeout=10
26189         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26190         # ensure ost1 is connected
26191         stat $DIR/$tfile >/dev/null || error "can't stat"
26192         wait_osc_import_state client ost1 FULL
26193         # no locks, no reqs to let the connection idle
26194         cancel_lru_locks osc
26195
26196 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26197         $LCTL set_param fail_loc=0x80000533
26198         sleep 15
26199         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26200 }
26201 run_test 812c "idle import vs lock enqueue race"
26202
26203 test_813() {
26204         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26205         [ -z "$file_heat_sav" ] && skip "no file heat support"
26206
26207         local readsample
26208         local writesample
26209         local readbyte
26210         local writebyte
26211         local readsample1
26212         local writesample1
26213         local readbyte1
26214         local writebyte1
26215
26216         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26217         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26218
26219         $LCTL set_param -n llite.*.file_heat=1
26220         echo "Turn on file heat"
26221         echo "Period second: $period_second, Decay percentage: $decay_pct"
26222
26223         echo "QQQQ" > $DIR/$tfile
26224         echo "QQQQ" > $DIR/$tfile
26225         echo "QQQQ" > $DIR/$tfile
26226         cat $DIR/$tfile > /dev/null
26227         cat $DIR/$tfile > /dev/null
26228         cat $DIR/$tfile > /dev/null
26229         cat $DIR/$tfile > /dev/null
26230
26231         local out=$($LFS heat_get $DIR/$tfile)
26232
26233         $LFS heat_get $DIR/$tfile
26234         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26235         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26236         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26237         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26238
26239         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26240         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26241         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26242         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26243
26244         sleep $((period_second + 3))
26245         echo "Sleep $((period_second + 3)) seconds..."
26246         # The recursion formula to calculate the heat of the file f is as
26247         # follow:
26248         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26249         # Where Hi is the heat value in the period between time points i*I and
26250         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26251         # to the weight of Ci.
26252         out=$($LFS heat_get $DIR/$tfile)
26253         $LFS heat_get $DIR/$tfile
26254         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26255         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26256         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26257         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26258
26259         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26260                 error "read sample ($readsample) is wrong"
26261         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26262                 error "write sample ($writesample) is wrong"
26263         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26264                 error "read bytes ($readbyte) is wrong"
26265         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26266                 error "write bytes ($writebyte) is wrong"
26267
26268         echo "QQQQ" > $DIR/$tfile
26269         echo "QQQQ" > $DIR/$tfile
26270         echo "QQQQ" > $DIR/$tfile
26271         cat $DIR/$tfile > /dev/null
26272         cat $DIR/$tfile > /dev/null
26273         cat $DIR/$tfile > /dev/null
26274         cat $DIR/$tfile > /dev/null
26275
26276         sleep $((period_second + 3))
26277         echo "Sleep $((period_second + 3)) seconds..."
26278
26279         out=$($LFS heat_get $DIR/$tfile)
26280         $LFS heat_get $DIR/$tfile
26281         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26282         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26283         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26284         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26285
26286         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26287                 4 * $decay_pct) / 100") -eq 1 ] ||
26288                 error "read sample ($readsample1) is wrong"
26289         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26290                 3 * $decay_pct) / 100") -eq 1 ] ||
26291                 error "write sample ($writesample1) is wrong"
26292         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26293                 20 * $decay_pct) / 100") -eq 1 ] ||
26294                 error "read bytes ($readbyte1) is wrong"
26295         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26296                 15 * $decay_pct) / 100") -eq 1 ] ||
26297                 error "write bytes ($writebyte1) is wrong"
26298
26299         echo "Turn off file heat for the file $DIR/$tfile"
26300         $LFS heat_set -o $DIR/$tfile
26301
26302         echo "QQQQ" > $DIR/$tfile
26303         echo "QQQQ" > $DIR/$tfile
26304         echo "QQQQ" > $DIR/$tfile
26305         cat $DIR/$tfile > /dev/null
26306         cat $DIR/$tfile > /dev/null
26307         cat $DIR/$tfile > /dev/null
26308         cat $DIR/$tfile > /dev/null
26309
26310         out=$($LFS heat_get $DIR/$tfile)
26311         $LFS heat_get $DIR/$tfile
26312         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26313         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26314         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26315         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26316
26317         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26318         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26319         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26320         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26321
26322         echo "Trun on file heat for the file $DIR/$tfile"
26323         $LFS heat_set -O $DIR/$tfile
26324
26325         echo "QQQQ" > $DIR/$tfile
26326         echo "QQQQ" > $DIR/$tfile
26327         echo "QQQQ" > $DIR/$tfile
26328         cat $DIR/$tfile > /dev/null
26329         cat $DIR/$tfile > /dev/null
26330         cat $DIR/$tfile > /dev/null
26331         cat $DIR/$tfile > /dev/null
26332
26333         out=$($LFS heat_get $DIR/$tfile)
26334         $LFS heat_get $DIR/$tfile
26335         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26336         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26337         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26338         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26339
26340         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26341         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26342         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26343         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26344
26345         $LFS heat_set -c $DIR/$tfile
26346         $LCTL set_param -n llite.*.file_heat=0
26347         echo "Turn off file heat support for the Lustre filesystem"
26348
26349         echo "QQQQ" > $DIR/$tfile
26350         echo "QQQQ" > $DIR/$tfile
26351         echo "QQQQ" > $DIR/$tfile
26352         cat $DIR/$tfile > /dev/null
26353         cat $DIR/$tfile > /dev/null
26354         cat $DIR/$tfile > /dev/null
26355         cat $DIR/$tfile > /dev/null
26356
26357         out=$($LFS heat_get $DIR/$tfile)
26358         $LFS heat_get $DIR/$tfile
26359         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26360         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26361         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26362         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26363
26364         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26365         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26366         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26367         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26368
26369         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26370         rm -f $DIR/$tfile
26371 }
26372 run_test 813 "File heat verfication"
26373
26374 test_814()
26375 {
26376         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26377         echo -n y >> $DIR/$tfile
26378         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26379         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26380 }
26381 run_test 814 "sparse cp works as expected (LU-12361)"
26382
26383 test_815()
26384 {
26385         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26386         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26387 }
26388 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26389
26390 test_816() {
26391         local ost1_imp=$(get_osc_import_name client ost1)
26392         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26393                          cut -d'.' -f2)
26394
26395         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26396         # ensure ost1 is connected
26397
26398         stat $DIR/$tfile >/dev/null || error "can't stat"
26399         wait_osc_import_state client ost1 FULL
26400         # no locks, no reqs to let the connection idle
26401         cancel_lru_locks osc
26402         lru_resize_disable osc
26403         local before
26404         local now
26405         before=$($LCTL get_param -n \
26406                  ldlm.namespaces.$imp_name.lru_size)
26407
26408         wait_osc_import_state client ost1 IDLE
26409         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26410         now=$($LCTL get_param -n \
26411               ldlm.namespaces.$imp_name.lru_size)
26412         [ $before == $now ] || error "lru_size changed $before != $now"
26413 }
26414 run_test 816 "do not reset lru_resize on idle reconnect"
26415
26416 cleanup_817() {
26417         umount $tmpdir
26418         exportfs -u localhost:$DIR/nfsexp
26419         rm -rf $DIR/nfsexp
26420 }
26421
26422 test_817() {
26423         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26424
26425         mkdir -p $DIR/nfsexp
26426         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26427                 error "failed to export nfs"
26428
26429         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26430         stack_trap cleanup_817 EXIT
26431
26432         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26433                 error "failed to mount nfs to $tmpdir"
26434
26435         cp /bin/true $tmpdir
26436         $DIR/nfsexp/true || error "failed to execute 'true' command"
26437 }
26438 run_test 817 "nfsd won't cache write lock for exec file"
26439
26440 test_818() {
26441         mkdir $DIR/$tdir
26442         $LFS setstripe -c1 -i0 $DIR/$tfile
26443         $LFS setstripe -c1 -i1 $DIR/$tfile
26444         stop $SINGLEMDS
26445         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26446         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26447         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26448                 error "start $SINGLEMDS failed"
26449         rm -rf $DIR/$tdir
26450 }
26451 run_test 818 "unlink with failed llog"
26452
26453 test_819a() {
26454         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26455         cancel_lru_locks osc
26456         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26457         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26458         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26459         rm -f $TDIR/$tfile
26460 }
26461 run_test 819a "too big niobuf in read"
26462
26463 test_819b() {
26464         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26465         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26466         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26467         cancel_lru_locks osc
26468         sleep 1
26469         rm -f $TDIR/$tfile
26470 }
26471 run_test 819b "too big niobuf in write"
26472
26473
26474 function test_820_start_ost() {
26475         sleep 5
26476
26477         for num in $(seq $OSTCOUNT); do
26478                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26479         done
26480 }
26481
26482 test_820() {
26483         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26484
26485         mkdir $DIR/$tdir
26486         umount_client $MOUNT || error "umount failed"
26487         for num in $(seq $OSTCOUNT); do
26488                 stop ost$num
26489         done
26490
26491         # mount client with no active OSTs
26492         # so that the client can't initialize max LOV EA size
26493         # from OSC notifications
26494         mount_client $MOUNT || error "mount failed"
26495         # delay OST starting to keep this 0 max EA size for a while
26496         test_820_start_ost &
26497
26498         # create a directory on MDS2
26499         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26500                 error "Failed to create directory"
26501         # open intent should update default EA size
26502         # see mdc_update_max_ea_from_body()
26503         # notice this is the very first RPC to MDS2
26504         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26505         ret=$?
26506         echo $out
26507         # With SSK, this situation can lead to -EPERM being returned.
26508         # In that case, simply retry.
26509         if [ $ret -ne 0 ] && $SHARED_KEY; then
26510                 if echo "$out" | grep -q "not permitted"; then
26511                         cp /etc/services $DIR/$tdir/mds2
26512                         ret=$?
26513                 fi
26514         fi
26515         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26516 }
26517 run_test 820 "update max EA from open intent"
26518
26519 test_822() {
26520         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26521
26522         save_lustre_params mds1 \
26523                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26524         do_facet $SINGLEMDS "$LCTL set_param -n \
26525                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26526         do_facet $SINGLEMDS "$LCTL set_param -n \
26527                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26528
26529         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26530         local maxage=$(do_facet mds1 $LCTL get_param -n \
26531                        osp.$FSNAME-OST0000*MDT0000.maxage)
26532         sleep $((maxage + 1))
26533
26534         #define OBD_FAIL_NET_ERROR_RPC          0x532
26535         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26536
26537         stack_trap "restore_lustre_params < $p; rm $p"
26538
26539         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26540                       osp.$FSNAME-OST0000*MDT0000.create_count")
26541         for i in $(seq 1 $count); do
26542                 touch $DIR/$tfile.${i} || error "touch failed"
26543         done
26544 }
26545 run_test 822 "test precreate failure"
26546
26547 #
26548 # tests that do cleanup/setup should be run at the end
26549 #
26550
26551 test_900() {
26552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26553         local ls
26554
26555         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26556         $LCTL set_param fail_loc=0x903
26557
26558         cancel_lru_locks MGC
26559
26560         FAIL_ON_ERROR=true cleanup
26561         FAIL_ON_ERROR=true setup
26562 }
26563 run_test 900 "umount should not race with any mgc requeue thread"
26564
26565 # LUS-6253/LU-11185
26566 test_901() {
26567         local oldc
26568         local newc
26569         local olds
26570         local news
26571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26572
26573         # some get_param have a bug to handle dot in param name
26574         cancel_lru_locks MGC
26575         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26576         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26577         umount_client $MOUNT || error "umount failed"
26578         mount_client $MOUNT || error "mount failed"
26579         cancel_lru_locks MGC
26580         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26581         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26582
26583         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26584         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26585
26586         return 0
26587 }
26588 run_test 901 "don't leak a mgc lock on client umount"
26589
26590 # LU-13377
26591 test_902() {
26592         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26593                 skip "client does not have LU-13377 fix"
26594         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26595         $LCTL set_param fail_loc=0x1415
26596         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26597         cancel_lru_locks osc
26598         rm -f $DIR/$tfile
26599 }
26600 run_test 902 "test short write doesn't hang lustre"
26601
26602 complete $SECONDS
26603 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26604 check_and_cleanup_lustre
26605 if [ "$I_MOUNTED" != "yes" ]; then
26606         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26607 fi
26608 exit_status